Codebase list tpm2-tss / 637b850
Import Debian changes 2.4.0-1 tpm2-tss (2.4.0-1) unstable; urgency=low [ Ying-Chun Liu (PaulLiu) <paulliu@debian.org> ] * New upstream release Ying-Chun Liu (PaulLiu) 4 years ago
296 changed file(s) with 64515 addition(s) and 1185 deletion(s). Raw diff Collapse all Expand all
0 #!/usr/bin/env bash
1 # SPDX-License-Identifier: BSD-3-Clause
2
3 source $TRAVIS_BUILD_DIR/.ci/docker-prelude.sh
4
5 export PATH=$PATH:$TRAVIS_BUILD_DIR/cov-analysis/bin
6
7 if [[ "$CC" == clang* ]]; then
8 echo "Coverity scan branch detected, not running with clang...exiting!"
9 exit 0
10 fi
11
12 if [ "$TRAVIS_BRANCH" != "coverity_scan" ]; then
13 echo "coverity.run invoked for non-coverity branch $TRAVIS_BRANCH...exiting!"
14 exit 1
15 fi
16
17 echo "Performing build with Coverity Scan"
18 rm -fr $TRAVIS_BUILD_DIR/cov-int
19 ./bootstrap && ./configure && make clean
20 cov-build --dir $TRAVIS_BUILD_DIR/cov-int make -j $(nproc)
21
22 echo "Collecting Coverity data for submission"
23 rm -fr README
24 export AUTHOR="$(git log -1 $TRAVIS_COMMIT --pretty="%aN")"
25 echo "Name: $AUTHOR" >> README
26 echo "Email: tadeusz.struk@intel.com" >> README
27 echo "Project: 01org/TPM2.0-TSS" >> README
28 echo "Build-Version: $TRAVIS_COMMIT" >> README
29 echo "Description: $TRAVIS_REPO_SLUG $TRAVIS_BRANCH" >> README
30 echo "Submitted-by: tpm2-tss CI" >> README
31 rm -fr tpm2-tss-scan.tgz
32 tar -czf $TRAVIS_BUILD_DIR/tpm2-tss-scan.tgz README cov-int
33
34 rm -fr README cov-int
0 #!/usr/bin/env bash
1 # SPDX-License-Identifier: BSD-3-Clause
2
3 # all command failures are fatal
4 set -e
5
6 WORKSPACE=`dirname $TRAVIS_BUILD_DIR`
7
8 echo "Workspace: $WORKSPACE"
9
10 source $TRAVIS_BUILD_DIR/.ci/download-deps.sh
11
12 get_deps "$WORKSPACE"
13
14 export LD_LIBRARY_PATH=/usr/local/lib/
15 export PATH=/root/.local/bin/:/ibmtpm974/src:$PATH
16
17 echo "echo changing to $TRAVIS_BUILD_DIR"
18 # Change to the the travis build dir
19 cd $TRAVIS_BUILD_DIR
0 CC
1 CXX
2 COVERITY_SCAN_TOKEN
3 COVERALLS_REPO_TOKEN
4
5 TRAVIS_BUILD_DIR=/workspace/tpm2-tss
6
7 TRAVIS_BRANCH
8 TRAVIS_COMMIT
9 TRAVIS_REPO_SLUG
10
11 ENABLE_COVERAGE
12
13 SCANBUILD
14 WITH_TCTI_ASYNC
15 WITH_TCTI_PARTIAL
16 WITH_CRYPTO
17 GEN_FUZZ
0 #!/usr/bin/env bash
1 # SPDX-License-Identifier: BSD-3-Clause
2
3 set -e
4
5 source $TRAVIS_BUILD_DIR/.ci/docker-prelude.sh
6
7 export CONFIGURE_OPTIONS=
8
9 if [ -d build ]; then
10 rm -rf build
11 fi
12
13 if [ -d ./build-no-tests ]; then
14 rm -rf build-no-tests
15 fi
16
17 # Do not run tests when building on coverity_scan branch
18 if [ "$COVERITY_SCAN_BRANCH" == 1 ]; then
19 echo "Coverity scan branch detected, not running build nor tests...exiting!"
20 exit 0
21 fi
22
23 if [ -z "$WITH_CRYPTO" ]; then
24 echo "variable WITH_CRYPTO not set, defaulting to ossl"
25 export WITH_CRYPTO="ossl"
26 fi
27
28 if [ "$WITH_CRYPTO" != "ossl" ]; then
29 export CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --disable-fapi"
30 fi
31
32 ./bootstrap
33
34 # Is it a fuzz run, if so build the fuzz test and exit.
35 if [ "$GEN_FUZZ" == "1" ]; then
36 ./configure --with-fuzzing=libfuzzer --enable-tcti-fuzzing --disable-tcti-device --disable-tcti-mssim --disable-shared --with-crypto="$WITH_CRYPTO"
37 make -j$(nproc) check
38 exit 0
39 fi
40
41 #
42 # General build runs
43 #
44
45 # build with no tests enabled
46 mkdir ./build-no-tests
47 pushd ./build-no-tests
48
49 echo "PWD: $(pwd)"
50 echo "ls -la ../ $(ls -la ../)"
51
52 ../configure --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
53 make -j$(nproc)
54 popd
55
56 # build with all tests enabled
57 mkdir ./build
58 pushd ./build
59
60 if [ "$CC" == "gcc" ]; then
61 export CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --enable-code-coverage";
62 fi
63
64 if [ "$SCANBUILD" == "yes" ]; then
65 scan-build --status-bugs ../configure --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --enable-unit --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
66 elif [ "$CC" == "clang" ]; then
67 ../configure --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --enable-unit --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
68 else
69 ../configure --with-sanitizer=undefined --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --enable-unit --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
70 fi
71
72 if [ "$SCANBUILD" == "yes" ]; then
73 scan-build --status-bugs make -j distcheck
74 elif [ "$CC" == "clang" ]; then
75 make -j distcheck
76 else
77 make -j check
78 fi
79
80 popd
81
82 # back in root git directory, check for whitespace errors. We do this post CI
83 # so people can verify the rest of their patch works in CI before dying.
84 # git diff --check fails with a non-zero return code causing the shell to die
85 # as it has a set -e executed.
86 [ -z "$TRAVIS_TAG" ] && git diff --check origin/${TRAVIS_BRANCH:-master}
87
88 if [ "$ENABLE_COVERAGE" == "true" ]; then
89 bash <(curl -s https://codecov.io/bash)
90 else
91 echo "ENABLE_COVERAGE not true, got \"$ENABLE_COVERAGE\""
92 fi
93
94 exit 0
0 #!/usr/bin/env bash
1 # SPDX-License-Identifier: BSD-3-Clause
2
3 function get_deps() {
4
5 echo "no deps"
6 }
0 #!/usr/bin/env bash
1
2 set -e
3
4 # if no DOCKER_TAG is set, warn and default to fedora-30
5 if [ -z "$DOCKER_TAG" ]; then
6 echo "WARN: DOCKER_TAG is not set, defaulting to fedora-30"
7 export DOCKER_TAG="fedora-30"
8 fi
9
10 #
11 # Docker starts you in a cloned repo of your project with the PR checkout out.
12 # We want those changes IN the docker image, so use the -v option to mount the
13 # project repo in the docker image.
14 #
15 # Also, pass in any env variables required for the build via .ci/docker.env file
16 #
17 # Execute the build and test procedure by running .ci/docker.run
18 #
19 if [ "$TRAVIS_BRANCH" != "coverity_scan" ]; then
20 echo "Running non-coverity build"
21 # Do normal CI script
22 ci_env=$(bash <(curl -s https://codecov.io/env))
23 docker run $ci_env --env-file .ci/docker.env \
24 -v "$(pwd):/workspace/tpm2-tss" "tpm2software/tpm2-tss:$DOCKER_TAG" \
25 /bin/bash -c '/workspace/tpm2-tss/.ci/docker.run'
26
27 exit 0
28 fi
29
30 # branch is coverity_scan
31 echo "Running coverity build"
32
33 # Do coverity steps
34 # we don't run with clang and we only run if COVERITY_RUN is true
35 if [[ "$CC" == clang* || "$COVERITY_RUN" != "true" ]]; then
36 echo "Nothing to do on the coverity_scan branch...exiting!"
37 exit 0
38 fi
39
40 # ensure coverity_scan tool is available to the container
41 if [ ! -f "$(pwd)/coverity-analysis/bin/cov-build" ]; then
42 wget https://scan.coverity.com/download/linux64 --quiet --post-data "token=$COVERITY_SCAN_TOKEN&project=tpm2-software%2Ftpm2.0-tss" -O coverity_tool.tgz
43 wget https://scan.coverity.com/download/linux64 --quiet --post-data "token=$COVERITY_SCAN_TOKEN&project=tpm2-software%2Ftpm2.0-tss&md5=1" -O coverity_tool.md5
44 echo "$(cat coverity_tool.md5)" coverity_tool.tgz | md5sum -c
45 fi
46
47 echo "unpacking cov-analysis"
48 tar -xf coverity_tool.tgz
49 mv cov-analysis-* cov-analysis
50
51
52 # perform the scan
53 docker run --env-file .ci/docker.env \
54 -v "$(pwd):/workspace/tpm2-tss" "tpm2software/tpm2-tss:$DOCKER_TAG" \
55 /bin/bash -c '/workspace/tpm2-tss/.ci/coverity.run'
56
57 # upload the results
58 test -f "$(pwd)/tpm2-tss-scan.tgz"
59
60 echo "Submitting data to Coverity"
61 curl --form token="$COVERITY_SCAN_TOKEN" \
62 --form email=tadeusz.struk@intel.com \
63 --form project=tpm2-software/tpm2.0-tss \
64 --form file=@"$(pwd)/tpm2-tss-scan.tgz" \
65 --form version="$TRAVIS_COMMIT" \
66 --form description="$TRAVIS_REPO_SLUG $TRAVIS_BRANCH" \
67 https://scan.coverity.com/builds?project=tpm2-software%2Ftpm2.0-tss
68
69 rm -fr tpm2-tss-scan.tgz
70
71 exit 0
0 task:
1 env:
2 CFLAGS: "-I/usr/local/include -I/usr/local/openssl/include"
3 LDFLAGS: -L/usr/local/lib
4 ibmtpm_name: ibmtpm1119
5 freebsd_instance:
6 matrix:
7 image: freebsd-12-1-release-amd64
8 install_script:
9 - pkg upgrade -y
10 - pkg install -y gmake coreutils libtool pkgconf autoconf autoconf-archive
11 - pkg install -y automake libgcrypt openssl json-c cmocka uthash wget
12 - wget --quiet --show-progress --progress=dot:giga "https://downloads.sourceforge.net/project/ibmswtpm2/$ibmtpm_name.tar.gz"
13 - shasum -a256 $ibmtpm_name.tar.gz | grep ^b9eef79904e276aeaed2a6b9e4021442ef4d7dfae4adde2473bef1a6a4cd10fb
14 - mkdir -p $ibmtpm_name
15 - tar xvf $ibmtpm_name.tar.gz -C $ibmtpm_name && cd $ibmtpm_name/src \
16 && sed -i -e 's/gcc/clang/g' makefile \
17 && sed -i -e 's/-Wall //g' makefile \
18 && sed -i -e 's/-Werror //g' makefile \
19 && gmake -j && cp tpm_server /usr/local/bin
20 - cd -
21 - rm -fr $ibmtpm_name $ibmtpm_name.tar.gz
22 script:
23 ./bootstrap &&
24 ./configure --enable-unit=yes --with-crypto=ossl --disable-doxygen-doc --disable-dependency-tracking &&
25 gmake -j check
0 # Read the Docs configuration file
1 # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
2
3 version: 2
4 sphinx:
5 builder: html
6 configuration: sphinx/conf.py
0 sudo: required
01 language: c
2 services:
3 - docker
14 compiler:
2 - gcc
3 - clang
4
5 dist: xenial
6
7 cache: ccache
8
5 - gcc
6 - clang
97 env:
108 matrix:
11 - SCANBUILD=yes CC=clang WITH_TCTI_ASYNC=yes WITH_TCTI_PARTIAL=yes WITH_CRYPTO=ossl OPENSSL_BRANCH=OpenSSL_1_1_0-stable
12 - WITH_CRYPTO=ossl OPENSSL_BRANCH=OpenSSL_1_0_2-stable
13 - WITH_CRYPTO=ossl OPENSSL_BRANCH=OpenSSL_1_1_0-stable
14 - WITH_CRYPTO=gcrypt OPENSSL_BRANCH=NONE
15 - WITH_TCTI_ASYNC=yes WITH_TCTI_PARTIAL=yes WITH_CRYPTO=gcrypt OPENSSL_BRANCH=NONE
16 - WITH_TCTI_ASYNC=yes WITH_TCTI_PARTIAL=no WITH_CRYPTO=gcrypt OPENSSL_BRANCH=NONE
17 - WITH_TCTI_ASYNC=no WITH_TCTI_PARTIAL=yes WITH_CRYPTO=gcrypt OPENSSL_BRANCH=NONE
9 # ubuntu 16.04
10 - DOCKER_TAG=ubuntu-16.04
11 # ubuntu 18.04
12 - DOCKER_TAG=ubuntu-18.04
13 # fedora-30
14 - DOCKER_TAG=fedora-30
15 # opensuse-leap
16 - DOCKER_TAG=opensuse-leap
17
1818 global:
1919 # COVERITY_SCAN_TOKEN
2020 - secure: "ZD0KxBhO/CaSE/TOkW+H5nsBbaMolbIPv5DgctcjA1BlTckgc5lK4m+7BIR1Fft6gaeeLOoCY3qUm4kW++Bqk2bTsrx/HvrmVmrzMO572jA74x4E+5lynUnRVaAgBg7cVBcB0hZcUurx8FifNBbgnWlxT/nDWttVnglkz400GCE9/zy+VTJWqt4QAB+6qeKPiG3vRthQdWcHstBI8IIAbvp4rhSUajBBQeZ5ro5RPGNy+iHen+t6tyJmbjiP0Y4qjkKGbfwXHnsseEcuSJQuxSkQ9MWK6t93BFXFSPw5MjHIApMn+4CjRp2JMoVTVfe5fFeZEHxVUmAzy+e5eIeftrUtUlCI293UuxZnw/vpJczn3BWunlhhjqjsCwVeknzGHxlaT+ck8Et1Mdl/3nY/E9dt47/NOzXY2xrAz59GYsdKvvsPoCGgNlAub03Vl0W24I1kjppsmN/zFwazHGqoxIBTwrDOQUmZvPfXA3jAUozrfAdT3YjnRcCG7bbQmacFApqfUm/bqMgapAgozjjxpuBrO1wQSUjjH6NANZsP2Gpk0eAl7FOlBzbVgKPxCQozWCjpKOj3HMnXX458ZQWsboG5J00wwjw9DRNRCkeexLdi832L/BPhUY5JgRlTqqyKr9cr69DvogBF/pLytpSCciF6t9NqqGZYbBomXJLaG84="
2121 # run coverity scan on gcc build to keep from DOSing coverity
2222 - coverity_scan_run_condition='"$CC" = gcc'
23 - LD_LIBRARY_PATH="$(pwd)/osslinstall/usr/local/lib:/usr/lib"
24 - PATH="$(pwd)/ibmtpm/src:${PATH}"
2523
26 addons:
27 apt:
28 packages:
29 - autoconf-archive
30 - doxygen
31 - libcmocka-dev
32 - libcmocka0
33 - libgcrypt20-dev
34 - realpath
35 - lcov
36 - libssl-dev
37 - gnulib
38 coverity_scan:
39 project:
40 name: "01org/TPM2.0-TSS"
41 description: Build submitted via Travis-CI
42 notification_email: philip.b.tricca@intel.com
43 build_command_prepend: "./bootstrap && ./configure"
44 build_command: "make --jobs=$(nproc)"
45 branch_pattern: coverity_scan
46
47 install:
48 # Autoconf archive
49 - wget http://ftpmirror.gnu.org/autoconf-archive/autoconf-archive-2019.01.06.tar.xz
50 - sha256sum autoconf-archive-2019.01.06.tar.xz | grep -q 17195c833098da79de5778ee90948f4c5d90ed1a0cf8391b4ab348e2ec511e3f || travis_terminate 1
51 - tar xJf autoconf-archive-2019.01.06.tar.xz
52 - cp autoconf-archive-2019.01.06/m4/ax_code_coverage.m4 m4/
53 - cp autoconf-archive-2019.01.06/m4/ax_is_release.m4 m4/
54 - cp autoconf-archive-2019.01.06/m4/ax_prog_doxygen.m4 m4/
55 # IBM-TPM
56 - wget https://download.01.org/tpm2/ibmtpm974.tar.gz
57 - sha256sum ibmtpm974.tar.gz | grep -q ^8e45d86129a0adb95fee4cee51f4b1e5b2d81ed3e55af875df53f98f39eb7ad7 || travis_terminate 1
58 - mkdir ibmtpm
59 - tar axf ibmtpm974.tar.gz -C ibmtpm
60 - make -C ibmtpm/src -j$(nproc)
61 # 2.1.0 version of uthash
62 - wget https://github.com/troydhanson/uthash/archive/v2.1.0.tar.gz
63 - tar xzf v2.1.0.tar.gz
64 - mkdir -p $(pwd)/osslinstall/usr/local/include
65 - cp uthash-2.1.0/src/*.h $(pwd)/osslinstall/usr/local/include/
66 # OpenSSL 1.0.2 (Must come after all wgets, since it overrides libcrypto.so for the test-environment)
67 - |
68 if [ "$OPENSSL_BRANCH" != "NONE" ]; then
69 mkdir -p osslinstall/usr/local/bin
70 git clone --branch $OPENSSL_BRANCH --depth=1 https://github.com/openssl/openssl.git
71 pushd openssl
72 ./config --prefix=/usr/local --openssldir=/usr/local/openssl shared
73 make -j$(nproc)
74 if [ "$OPENSSL_BRANCH" == "OpenSSL_1_0_2-stable" ]; then
75 make install INSTALL_PREFIX=${PWD}/../osslinstall
76 else
77 make install DESTDIR=${PWD}/../osslinstall
78 fi
79 which openssl
80 popd
81 fi
82
83 before_script:
84 - ./bootstrap
24 matrix:
25 include:
26 # gcrypt testing
27 - env: DOCKER_TAG=fedora-30 WITH_CRYPTO=gcrypt
28 compiler: gcc
29 - env: DOCKER_TAG=opensuse-leap WITH_CRYPTO=gcrypt
30 compiler: clang
31 - env: DOCKER_TAG=ubuntu-16.04 WITH_CRYPTO=gcrypt
32 compiler: gcc
33 - env: DOCKER_TAG=ubuntu-18.04 WITH_CRYPTO=gcrypt
34 compiler: clang
35 # tcti async and partial read testing
36 - env: DOCKER_TAG=fedora-30 WITH_TCTI_ASYNC=yes WITH_TCTI_PARTIAL=yes WITH_CRYPTO=gcrypt
37 compiler: gcc
38 - env: DOCKER_TAG=fedora-30 WITH_TCTI_ASYNC=yes WITH_TCTI_PARTIAL=no
39 compiler: gcc
40 - env: DOCKER_TAG=fedora-30 WITH_TCTI_ASYNC=no WITH_TCTI_PARTIAL=yes
41 compiler: gcc
42 # coverage check
43 - env: DOCKER_TAG=ubuntu-18.04 ENABLE_COVERAGE=true
44 compiler: gcc
45 # scan build check
46 - env: DOCKER_TAG=fedora-30 SCANBUILD=yes WITH_TCTI_ASYNC=yes WITH_TCTI_PARTIAL=yes
47 compiler: clang
48 # check fuzz targets
49 - env: DOCKER_TAG=fedora-30 GEN_FUZZ=1 CXX=clang++ CC=clang
50 compiler: clang
8551
8652 script:
87 # Check for whitespace errors
88 - git diff --check $(git hash-object -t tree /dev/null)
89 # short-circuit normal build if we've already done a coverity scan
90 - |
91 if [ "${COVERITY_SCAN_BRANCH}" == 1 ]; then
92 echo "COVERITY_SCAN_BRANCH set, not running normal build."
93 exit 0
94 fi
95 # build with no tests enabled
96 - mkdir ./build-no-tests
97 - pushd ./build-no-tests
98 - ../configure --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --with-crypto=$WITH_CRYPTO CFLAGS=-I${PWD}/../osslinstall/usr/local/include LDFLAGS=-L${PWD}/../osslinstall/usr/local/lib
99 - make -j$(nproc)
100 - popd
101 # build with all tests enabled
102 - mkdir ./build
103 - pushd ./build
104 - |
105 if [ "$CC" == "gcc" ]; then
106 export CONFIGURE_OPTIONS="--enable-code-coverage";
107 fi
108 - |
109 if [ "$SCANBUILD" == "yes" ]; then
110 scan-build --status-bugs ../configure --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --enable-unit --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS CFLAGS=-I${PWD}/../osslinstall/usr/local/include LDFLAGS=-L${PWD}/../osslinstall/usr/local/lib
111 elif [ "$CC" == "clang" ]; then
112 ../configure --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --enable-unit --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS CFLAGS=-I${PWD}/../osslinstall/usr/local/include LDFLAGS=-L${PWD}/../osslinstall/usr/local/lib
113 else
114 ../configure --enable-tcti-partial-reads=$WITH_TCTI_PARTIAL --enable-tcti-device-async=$WITH_TCTI_ASYNC --enable-unit --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS CFLAGS=-I${PWD}/../osslinstall/usr/local/include LDFLAGS=-L${PWD}/../osslinstall/usr/local/lib
115 fi
116 - |
117 if [ "$SCANBUILD" == "yes" ]; then
118 scan-build --status-bugs make -j distcheck
119 elif [ "$CC" == "clang" ]; then
120 make -j distcheck
121 else
122 make -j check
123 fi
53 - ./.ci/travis.run
12454
125 after_success:
126 - |
127 if [ "$CC" == "gcc" ]; then
128 bash <(curl -s https://codecov.io/bash)
129 fi
130
131 # check fuzz targets
132 matrix:
133 include:
134 - env: WITH_CRYPTO=ossl OPENSSL_BRANCH=OpenSSL_1_1_0-stable GEN_FUZZ=1 CXX=clang++ CC=clang
135 compiler: clang
136 script:
137 - ./configure --with-fuzzing=libfuzzer --enable-tcti-fuzzing --disable-tcti-device --disable-tcti-mssim --disable-shared --with-crypto=$WITH_CRYPTO CFLAGS=-I${PWD}/osslinstall/usr/local/include LDFLAGS=-L${PWD}/osslinstall/usr/local/lib
138 - make -j$(nproc) check
55 after_failure:
56 - cat build/test-suite.log
22
33 The format is based on [Keep a Changelog](http://keepachangelog.com/)
44
5 ## [2.3.3] - 2020-02-18
6 ### Fixed
5 ## [2.4.0] - 2020-03-11
6 ### Added
7 - Added a new Feature API (FAPI) implementation
8 - Added Esys_TRSess_GetAuthRequired() ESAPI function
9 - Added Esys_TR_GetTpmHandle() SAPI function
10 - Added Esys_GetSysContext() SAPI function
11 - Added the with-sanitizer configure option
12 - Added CI for FreeBSD
13
14 ### Changed
15 - Changed MSSIM TCTI to be async capable
16 - Removed TCTI loaders from ESYS dependencies in pkg-config
17 - Changed getPollHandles to allow num_handles query
18 - Improved CI builds
19 - Converted builds to docker builds
20 - Number of fixes and improvements in the test code
21 - Changed tcti-device in non-async mode to allways block
22
23 ### Fixed
24 - Fixed hmac calculation for tpm2_clear command in ESAPI
725 - Fixed mixing salted and unsalted sessions in the same ESAPI context
826 - Removed use of VLAs from TPML marshal code
27 - Fixed setting C++ compiler for non-fuzzing builds at configure
28 - Fixed setting the name of session objects
29 - Fixed page alignment errors in Sys_Get/SetAuths functions
30 - Fixed potential buffer overflow in tcti_mssim_receive
31 - Fixed invalid memory alloc failure in Tss2_TctiLdr_Initialize
32 - Fixed list of exported symbols map for libtss2-mu
33 - Fixed resource name calculation in Esys_CreateLoaded
34 - Fixed keysize of ECC curve TPM2_ECC_NISTP224
35 - Fixed segmentation fault in tctildr if name_conf was too big
36 - Fixed memory leak in tctildr-tcti tests
37 - Fixed HMAC generation for policy sessions
938 - Added check for object node before calling compute_session_value function
1039 - Fixed auth calculation in Esys_StartAuthSession called with optional parameters
1140 - Fixed compute_encrypted_salt error handling in Esys_StartAuthSession
1241 - Fixed exported symbols map for libtss2-mu
1342
14 ## [2.3.2] - 2019-12-12
15 ### Fixed
16 - Fix unit tests on S390 architectures
17
18 ## [2.3.1] - 2019-08-30
19 ### Fixed
20 - Fixed HMAC generation for policy sessions
43 ### Removed
44 - Remove duplicate ESYS entries from map file
45 - Removed the private implementation of strndup from tctildr
2146
2247 ## [2.3.0] - 2019-08-13
2348 ### Added
22 COPY . /tmp/tpm2-tss/
33 WORKDIR /tmp/tpm2-tss
44 ENV LD_LIBRARY_PATH /usr/local/lib
5
6 # Install libjson-c
7 RUN apt-get update && apt-get install -y --no-install-recommends \
8 libjson-c-dev \
9 && rm -rf /var/lib/apt/lists/*
510
611 # Fuzzing
712 FROM base AS fuzzing
781781 @top_srcdir@/README.md \
782782 @top_srcdir@/include/tss2/tss2_esys.h \
783783 @top_srcdir@/src/tss2-esys \
784 @top_srcdir@/include/tss2/tss2_fapi.h \
785 @top_srcdir@/src/tss2-fapi \
784786 @top_srcdir@/test/integration/esys-audit.int.c \
785787 @top_srcdir@/test/integration/esys-certify-creation.int.c \
786788 @top_srcdir@/test/integration/esys-certify.int.c \
846848 @top_srcdir@/test/integration/esys-tr-getName-hierarchy.int.c \
847849 @top_srcdir@/test/integration/esys-unseal-password-auth.int.c \
848850 @top_srcdir@/test/integration/esys-verify-signature.int.c \
849 @top_srcdir@/test/integration/esys-zgen-2phase.int.c
851 @top_srcdir@/test/integration/esys-zgen-2phase.int.c \
852 @top_srcdir@/test/integration/fapi-data-crypt.int.c \
853 @top_srcdir@/test/integration/fapi-duplicate.int.c \
854 @top_srcdir@/test/integration/fapi-ext-public-key.int.c \
855 @top_srcdir@/test/integration/fapi-get-random.int.c \
856 @top_srcdir@/test/integration/fapi-info.int.c \
857 @top_srcdir@/test/integration/fapi-key-change-auth.int.c \
858 @top_srcdir@/test/integration/fapi-key-create-ckda-sign.int.c \
859 @top_srcdir@/test/integration/fapi-key-create-policies-sign.int.c \
860 @top_srcdir@/test/integration/fapi-key-create-policy-authorize-nv-sign.int.c \
861 @top_srcdir@/test/integration/fapi-key-create-policy-authorize-sign.int.c \
862 @top_srcdir@/test/integration/fapi-key-create-policy-nv-sign.int.c \
863 @top_srcdir@/test/integration/fapi-key-create-policy-or-sign.int.c \
864 @top_srcdir@/test/integration/fapi-key-create-policy-password-sign.int.c \
865 @top_srcdir@/test/integration/fapi-key-create-policy-pcr-sign.int.c \
866 @top_srcdir@/test/integration/fapi-key-create-policy-secret-nv-sign.int.c \
867 @top_srcdir@/test/integration/fapi-key-create-policy-signed.int.c \
868 @top_srcdir@/test/integration/fapi-key-create-sign.int.c \
869 @top_srcdir@/test/integration/fapi-key-create-sign-password-provision.int.c \
870 @top_srcdir@/test/integration/fapi-key-create-sign-policy-provision.int.c \
871 @top_srcdir@/test/integration/fapi-nv-authorizenv-cphash.int.c \
872 @top_srcdir@/test/integration/fapi-nv-extend.int.c \
873 @top_srcdir@/test/integration/fapi-nv-increment.int.c \
874 @top_srcdir@/test/integration/fapi-nv-ordinary.int.c \
875 @top_srcdir@/test/integration/fapi-nv-set-bits.int.c \
876 @top_srcdir@/test/integration/fapi-nv-written-policy.int.c \
877 @top_srcdir@/test/integration/fapi-pcr-test.int.c \
878 @top_srcdir@/test/integration/fapi-platform-certificates.int.c \
879 @top_srcdir@/test/integration/fapi-quote.int.c \
880 @top_srcdir@/test/integration/fapi-unseal.int.c
881
850882 # This tag can be used to specify the character encoding of the source files
851883 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
852884 # libiconv (or the iconv built into libc) for the transcoding. See the libiconv
941973 # that contain images that are to be included in the documentation (see the
942974 # \image command).
943975
944 IMAGE_PATH =
976 IMAGE_PATH = @top_srcdir@/doc/
945977
946978 # The INPUT_FILTER tag can be used to specify a program that doxygen should
947979 # invoke to filter for each input file. Doxygen will invoke the filter program
1313 * C library development libraries and header files
1414 * pkg-config
1515 * doxygen
16 * OpenSSL development libraries and header files
16 * OpenSSL development libraries and header files, or optionally libgcrypt
17 * libcurl development libraries
18
19 * Please note that with FAPI enabled, the only option for the crypto backend is
20 OpenSSL. If only ESAPI is enabled it can work with either openSSL or libgrcypt,
21 however libgcrypt-dev is required as a dependency for the configure script
22 because it uses the AM_PATH_LIBGCRYPT macro.
23 See https://github.com/tpm2-software/tpm2-tss/issues/1365 for more info.
1724
1825 The following are dependencies only required when building test suites.
1926 * Integration test suite (see ./configure option --enable-integration):
4754 uthash-dev \
4855 autoconf \
4956 doxygen \
50 libltdl-dev
57 libjson-c-dev \
58 libini-config-dev \
59 libcurl-dev \
60 libgcrypt-dev
5161 ```
5262 Note: In some Ubuntu versions, the lcov and autoconf-archive packages are incompatible with each other. It is recommended to download autoconf-archive directly from upstream and copy `ax_code_coverage.m4` and `ax_prog_doxygen.m4` to the `m4/` subdirectory of your tpm2-tss directory.
5363
180190
181191 tpm2-tss is now in your working directory and contains all the built files.
182192
183 To rebuild using your local changes mount your tmp2-tss directory as a volume.
193 To rebuild using your local changes mount your tpm2-tss directory as a volume.
184194
185195 ```console
186196 $ docker run --rm -ti -v $PWD:/tmp/tpm2-tss tpm2-tss \
00 Tadeusz Struk <tadeusz.struk@intel.com>
11 Andreas Fuchs <andreas.fuchs@sit.fraunhofer.de>
2 Philip Tricca <philip.b.tricca@intel.com>
2 Bill Roberts <william.c.roberts@intel.com>
33 # All rights reserved.
44
55 TESTS_CFLAGS = $(AM_CFLAGS) $(LIBCRYPTO_CFLAGS) -I$(srcdir)/src/tss2-mu \
6 -I$(srcdir)/src/tss2-sys -I$(srcdir)/src/tss2-esys \
6 -I$(srcdir)/src/tss2-sys -I$(srcdir)/src/tss2-esys -I$(srcdir)/src/tss2-fapi \
77 -Wno-unused-parameter -Wno-missing-field-initializers
88 TESTS_LDADD = $(check_LTLIBRARIES) $(lib_LTLIBRARIES) \
99 $(LIBCRYPTO_LIBS) $(libutil)
1717 else
1818 INT_LOG_COMPILER = $(srcdir)/script/int-log-compiler.sh
1919 endif
20 EXTRA_DIST += $(srcdir)/script/int-log-compiler.sh $(srcdir)/script/int-log-compiler-ptpm.sh
20 EXTRA_DIST += $(srcdir)/script/int-log-compiler.sh $(srcdir)/script/int-log-compiler-ptpm.sh \
21 $(srcdir)/script/ekca/create_ca.sh $(srcdir)/script/ekca/ek.cnf \
22 $(srcdir)/script/ekca/intermed-ca.cnf $(srcdir)/script/ekca/root-ca.cnf
2123 AM_TESTS_ENVIRONMENT = PATH="$(PATH)"
2224
2325 check-programs: $(check_PROGRAMS)
4042 test_helper_tpm_dumpstate_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
4143 test_helper_tpm_dumpstate_LDFLAGS = $(TESTS_LDFLAGS)
4244 test_helper_tpm_dumpstate_LDADD = $(TESTS_LDADD)
45
46 check_PROGRAMS += test/helper/tpm_getek
47 test_helper_tpm_getek_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
48 test_helper_tpm_getek_LDFLAGS = $(TESTS_LDFLAGS) -lcrypto
49 test_helper_tpm_getek_LDADD = $(TESTS_LDADD)
50
51 check_PROGRAMS += test/helper/tpm_getek_ecc
52 test_helper_tpm_getek_ecc_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
53 test_helper_tpm_getek_ecc_LDFLAGS = $(TESTS_LDFLAGS) -lcrypto
54 test_helper_tpm_getek_ecc_LDADD = $(TESTS_LDADD)
55
56
57 check_PROGRAMS += test/helper/tpm_writeekcert
58 test_helper_tpm_writeekcert_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
59 test_helper_tpm_writeekcert_LDFLAGS = $(TESTS_LDFLAGS)
60 test_helper_tpm_writeekcert_LDADD = $(TESTS_LDADD)
4361 endif #ENABLE_INTEGRATION
4462
4563 if UNIT
5068 test/unit/key-value-parse \
5169 test/unit/log \
5270 test/unit/tcti-device \
53 test/unit/tcti-mssim \
5471 test/unit/tctildr \
5572 test/unit/tctildr-dl \
5673 test/unit/tctildr-nodl \
6885 test/unit/TPMU-marshal \
6986 test/unit/sys-execute \
7087 test/unit/tss2_rc
88 if ENABLE_TCTI_MSSIM
89 TESTS_UNIT += test/unit/tcti-mssim
90 endif
7191 if ESAPI
7292 TESTS_UNIT += \
7393 test/unit/esys-context-null \
80100 test/unit/esys-crypto
81101
82102 endif ESAPI
103 if FAPI
104 fapiLDFLAGS = -ljson-c
105 TESTS_UNIT += \
106 test/unit/fapi-json
107 endif FAPI
83108 endif #UNIT
84109
85110 if ENABLE_INTEGRATION
91116 test/integration/sapi-asymmetric-encrypt-decrypt.int \
92117 test/integration/sapi-nv-policy-locality.int \
93118 test/integration/sapi-nv-readwrite.int \
119 test/integration/sapi-hmac-auth.int \
94120 test/integration/sapi-primary-rsa-2K-aes128cfb.int \
95121 test/integration/sapi-create-keyedhash-sha1-hmac.int \
96122 test/integration/sapi-encrypt-decrypt.int \
118144 ESYS_TESTS_INTEGRATION_DESTRUCTIVE = \
119145 test/integration/esys-change-eps.int \
120146 test/integration/esys-clear.int \
147 test/integration/esys-tpm-clear-auth.int \
121148 test/integration/esys-clear-session.int \
122149 test/integration/esys-field-upgrade.int \
123150 test/integration/esys-firmware-read.int \
182209 test/integration/esys-tr-fromTpmPublic-nv.int \
183210 test/integration/esys-tr-fromTpmPublic-session.int \
184211 test/integration/esys-tr-getName-hierarchy.int \
212 test/integration/esys-tr-getTpmHandle-key.int \
213 test/integration/esys-tr-getTpmHandle-nv.int \
185214 test/integration/esys-unseal-password-auth.int \
186215 test/integration/esys-verify-signature.int \
187216 test/integration/esys-ecdh-keygen.int \
221250
222251 else # TESTPTPM
223252 TESTS_INTEGRATION += $(ESYS_TESTS_INTEGRATION_MANDATORY) $(ESYS_TESTS_INTEGRATION_OPTIONAL) $(ESYS_TESTS_INTEGRATION_DESTRUCTIVE)
253
224254 endif # TESTPTPM
225255
226256 endif #ESAPI
257
258 if FAPI
259 TESTS_CFLAGS += -DTOP_SOURCEDIR"=\"$(top_srcdir)\""
260 FAPI_TESTS_INTEGRATION = \
261 test/integration/fapi-data-crypt.int \
262 test/integration/fapi-data-crypt-rsa.int \
263 test/integration/fapi-duplicate.int \
264 test/integration/fapi-ext-public-key.int \
265 test/integration/fapi-get-random.int \
266 test/integration/fapi-platform-certificates.int \
267 test/integration/fapi-key-create-sign.int \
268 test/integration/fapi-key-create-sign-password-provision.int \
269 test/integration/fapi-key-create-sign-rsa.int \
270 test/integration/fapi-key-create-policy-authorize-sign.int \
271 test/integration/fapi-key-create-policy-authorize-sign-rsa.int \
272 test/integration/fapi-key-create-policy-authorize-nv-sign.int \
273 test/integration/fapi-key-create-policy-secret-nv-sign.int \
274 test/integration/fapi-key-create-policy-pcr-sign.int \
275 test/integration/fapi-key-create-policy-signed.int \
276 test/integration/fapi-key-create-policy-signed-ecc.int \
277 test/integration/fapi-key-create-policy-nv-sign.int \
278 test/integration/fapi-key-create-policy-or-sign.int \
279 test/integration/fapi-key-create-policy-password-sign.int \
280 test/integration/fapi-key-create-policy-countertimer-sign.int \
281 test/integration/fapi-key-create-policy-physical-presence-sign.int \
282 test/integration/fapi-key-create-policy-locality-sign.int \
283 test/integration/fapi-key-create-policy-command-code-sign.int \
284 test/integration/fapi-key-create-policy-auth-value-sign.int \
285 test/integration/fapi-key-create-ckda-sign.int \
286 test/integration/fapi-key-change-auth.int \
287 test/integration/fapi-key-create-sign-persistent.int \
288 test/integration/fapi-key-create-sign-password.int \
289 test/integration/fapi-key-create-ckda-sign-password.int \
290 test/integration/fapi-key-create-sign-password-da.int \
291 test/integration/fapi-key-create-ckda-sign-password-da.int \
292 test/integration/fapi-nv-authorizenv-cphash.int \
293 test/integration/fapi-nv-ordinary.int \
294 test/integration/fapi-nv-written-policy.int \
295 test/integration/fapi-nv-extend.int \
296 test/integration/fapi-nv-increment.int \
297 test/integration/fapi-nv-set-bits.int \
298 test/integration/fapi-pcr-test.int \
299 test/integration/fapi-quote.int \
300 test/integration/fapi-quote-rsa.int \
301 test/integration/fapi-info.int \
302 test/integration/fapi-unseal.int
303
304 if TESTPTPM
305 if PTPMDESTRUCTIVE
306 FAPI_TESTS_INTEGRATION += test/integration/fapi-key-create-sign-policy-provision.int
307 endif #PTPMDESTRUCTIVE
308 endif #TESTPTPM
309
310 if !TESTPTPM
311 FAPI_TESTS_INTEGRATION += \
312 test/integration/fapi-key-create-sign-policy-provision.int \
313 test/integration/fapi-provision-fingerprint.int \
314 test/integration/fapi-provision-certificate.int \
315 test/integration/fapi-provision-fingerprint_ecc.int \
316 test/integration/fapi-provision-certificate_ecc.int
317 endif #!TESTPTPM
318
319 TESTS_INTEGRATION += $(FAPI_TESTS_INTEGRATION)
320
321 endif #FAPI
322
227323 endif #ENABLE_INTEGRATION
228324
229325 CLEANFILES += \
326 test/integration/*.crt \
327 test/integration/*.crl \
230328 test/integration/*.int_state* \
231329 test/integration/*.log \
330 test/integration/*.int_ek* \
331 test/integration/*.int_*-ca.pem \
332 test/tpmclient/*.crt \
333 test/tpmclient/*.crl \
232334 test/tpmclient/*.int_state* \
233335 test/tpmclient/*.log \
336 test/tpmclient/*.int_ek* \
337 test/tpmclient/*.int_*-ca.pem \
234338 test/unit/*.log
235339
236340 if UNIT
237341 test_unit_tcti_device_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
238342 test_unit_tcti_device_LDADD = $(CMOCKA_LIBS) $(libtss2_mu) $(libutil)
239 test_unit_tcti_device_LDFLAGS = -Wl,--wrap=read -Wl,--wrap=write, -Wl,--wrap=poll
343 test_unit_tcti_device_LDFLAGS = -Wl,--wrap=read -Wl,--wrap=write, -Wl,--wrap=poll \
344 -Wl,--wrap=open
240345 test_unit_tcti_device_SOURCES = test/unit/tcti-device.c \
241346 src/tss2-tcti/tcti-common.c \
242347 src/tss2-tcti/tcti-device.c src/tss2-tcti/tcti-device.h
243348
349 if ENABLE_TCTI_MSSIM
244350 test_unit_tcti_mssim_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
245351 test_unit_tcti_mssim_LDADD = $(CMOCKA_LIBS) $(libtss2_mu) $(libutil)
246352 test_unit_tcti_mssim_LDFLAGS = -Wl,--wrap=connect,--wrap=read,--wrap=select,--wrap=write
247353 test_unit_tcti_mssim_SOURCES = test/unit/tcti-mssim.c \
248354 src/tss2-tcti/tcti-common.c \
249355 src/tss2-tcti/tcti-mssim.c src/tss2-tcti/tcti-mssim.h
356 endif
250357
251358 test_unit_tctildr_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
252359 test_unit_tctildr_LDADD = $(CMOCKA_LIBS) $(libutil)
389496 test_unit_esys_nulltcti_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS) $(TSS2_ESYS_CFLAGS_CRYPTO)
390497 test_unit_esys_nulltcti_LDADD = $(CMOCKA_LIBS) $(TESTS_LDADD) $(LIBADD_DL)
391498 test_unit_esys_nulltcti_LDFLAGS = $(TESTS_LDFLAGS) $(TSS2_ESYS_LDFLAGS_CRYPTO) \
392 $(LIBDL_LDFLAGS) -Wl,--wrap=Tss2_TctiLdr_Initialize
499 $(LIBDL_LDFLAGS) -Wl,--wrap=Tss2_TctiLdr_Initialize -Wl,--wrap=Tss2_TctiLdr_Finalize
393500 test_unit_esys_nulltcti_SOURCES = test/unit/esys-nulltcti.c \
394501 src/tss2-esys/esys_context.c \
395502 src/tss2-esys/esys_iutil.c \
407514 src/tss2-esys/esys_crypto.c \
408515 $(TSS2_ESYS_SRC_CRYPTO)
409516 endif # ESAPI
517
518 if FAPI
519
520 test_unit_fapi_json_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
521 test_unit_fapi_json_LDADD = $(CMOCKA_LIBS) $(TESTS_LDADD)
522 test_unit_fapi_json_LDFLAGS = $(TESTS_LDFLAGS) -ljson-c
523 test_unit_fapi_json_SOURCES = test/unit/fapi-json.c \
524 src/tss2-fapi/ifapi_json_deserialize.c \
525 src/tss2-fapi/ifapi_json_serialize.c \
526 src/tss2-fapi/ifapi_policy_json_deserialize.c \
527 src/tss2-fapi/ifapi_policy_json_serialize.c \
528 src/tss2-fapi/tpm_json_deserialize.c \
529 src/tss2-fapi/tpm_json_serialize.c
530
531 endif # FAPI
410532 endif # UNIT
411533
412534 if ENABLE_INTEGRATION
439561 test_integration_sapi_nv_readwrite_int_SOURCES = \
440562 test/integration/sapi-nv-readwrite.int.c test/integration/main-sapi.c
441563
564 test_integration_sapi_hmac_auth_int_CFLAGS = $(AM_CFLAGS) $(TESTS_CFLAGS)
565 test_integration_sapi_hmac_auth_int_LDADD = $(TESTS_LDADD)
566 test_integration_sapi_hmac_auth_int_SOURCES = \
567 test/integration/sapi-hmac-auth.int.c test/integration/main-sapi.c
568
442569 test_integration_sapi_primary_rsa_2K_aes128cfb_int_CFLAGS = $(AM_CFLAGS) $(TESTS_CFLAGS)
443570 test_integration_sapi_primary_rsa_2K_aes128cfb_int_LDADD = $(TESTS_LDADD)
444571 test_integration_sapi_primary_rsa_2K_aes128cfb_int_SOURCES = \
11361263 test/integration/esys-tr-getName-hierarchy.int.c \
11371264 test/integration/main-esapi.c test/integration/test-esapi.h
11381265
1266 test_integration_esys_tr_getTpmHandle_key_int_CFLAGS = $(TESTS_CFLAGS)
1267 test_integration_esys_tr_getTpmHandle_key_int_LDADD = $(TESTS_LDADD)
1268 test_integration_esys_tr_getTpmHandle_key_int_LDFLAGS = $(TESTS_LDFLAGS)
1269 test_integration_esys_tr_getTpmHandle_key_int_SOURCES = \
1270 test/integration/esys-tr-getTpmHandle-key.int.c \
1271 test/integration/main-esapi.c test/integration/test-esapi.h
1272
1273 test_integration_esys_tr_getTpmHandle_nv_int_CFLAGS = $(TESTS_CFLAGS)
1274 test_integration_esys_tr_getTpmHandle_nv_int_LDADD = $(TESTS_LDADD)
1275 test_integration_esys_tr_getTpmHandle_nv_int_LDFLAGS = $(TESTS_LDFLAGS)
1276 test_integration_esys_tr_getTpmHandle_nv_int_SOURCES = \
1277 test/integration/esys-tr-getTpmHandle-nv.int.c \
1278 test/integration/main-esapi.c test/integration/test-esapi.h
1279
11391280 test_integration_esys_unseal_password_auth_int_CFLAGS = $(TESTS_CFLAGS) $(TSS2_ESYS_CFLAGS_CRYPTO)
11401281 test_integration_esys_unseal_password_auth_int_LDADD = $(TESTS_LDADD)
11411282 test_integration_esys_unseal_password_auth_int_LDFLAGS = $(TESTS_LDFLAGS) $(TSS2_ESYS_LDFLAGS_CRYPTO) $(LIBDL_LDFLAGS)
11651306 test/integration/esys-auto-session-flags.int.c \
11661307 test/integration/main-esapi.c test/integration/test-esapi.h
11671308
1309 test_integration_esys_tpm_clear_auth_int_CFLAGS = $(TESTS_CFLAGS)
1310 test_integration_esys_tpm_clear_auth_int_LDADD = $(TESTS_LDADD)
1311 test_integration_esys_tpm_clear_auth_int_LDFLAGS = $(TESTS_LDFLAGS)
1312 test_integration_esys_tpm_clear_auth_int_SOURCES = \
1313 test/integration/esys-tpm-clear-auth.int.c \
1314 test/integration/main-esapi.c test/integration/test-esapi.h
1315
11681316 endif #ESAPI
11691317
11701318 test_integration_sapi_policy_template_int_CFLAGS = $(TESTS_CFLAGS)
11861334 test_integration_sapi_command_cancel_int_LDADD = $(TESTS_LDADD)
11871335 test_integration_sapi_command_cancel_int_SOURCES = test/integration/main-sapi.c \
11881336 test/integration/sapi-command-cancel.int.c src/util/log.c
1337
1338 if FAPI
1339 test_integration_fapi_get_random_int_CFLAGS = $(TESTS_CFLAGS)
1340 test_integration_fapi_get_random_int_LDADD = $(TESTS_LDADD)
1341 test_integration_fapi_get_random_int_LDFLAGS = $(TESTS_LDFLAGS)
1342 test_integration_fapi_get_random_int_SOURCES = \
1343 test/integration/fapi-get-random.int.c \
1344 test/integration/main-fapi.c test/integration/test-fapi.h
1345
1346 test_integration_fapi_platform_certificates_int_CFLAGS = $(TESTS_CFLAGS)
1347 test_integration_fapi_platform_certificates_int_LDADD = $(TESTS_LDADD)
1348 test_integration_fapi_platform_certificates_int_LDFLAGS = $(TESTS_LDFLAGS)
1349 test_integration_fapi_platform_certificates_int_SOURCES = \
1350 test/integration/fapi-platform-certificates.int.c \
1351 test/integration/main-fapi.c test/integration/test-fapi.h
1352
1353 test_integration_fapi_key_create_sign_int_CFLAGS = $(TESTS_CFLAGS)
1354 test_integration_fapi_key_create_sign_int_LDADD = $(TESTS_LDADD)
1355 test_integration_fapi_key_create_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1356 test_integration_fapi_key_create_sign_int_SOURCES = \
1357 test/integration/fapi-key-create-sign.int.c \
1358 test/integration/main-fapi.c test/integration/test-fapi.h
1359
1360 test_integration_fapi_key_create_sign_password_provision_int_CFLAGS = $(TESTS_CFLAGS)
1361 test_integration_fapi_key_create_sign_password_provision_int_LDADD = $(TESTS_LDADD)
1362 test_integration_fapi_key_create_sign_password_provision_int_LDFLAGS = $(TESTS_LDFLAGS)
1363 test_integration_fapi_key_create_sign_password_provision_int_SOURCES = \
1364 test/integration/fapi-key-create-sign-password-provision.int.c \
1365 test/integration/main-fapi.c test/integration/test-fapi.h
1366
1367 test_integration_fapi_key_create_sign_policy_provision_int_CFLAGS = $(TESTS_CFLAGS) \
1368 -DFAPI_PROFILE=\"P_RSA_sh_policy\" -DFAPI_TEST_EK_CERT_LESS
1369 test_integration_fapi_key_create_sign_policy_provision_int_LDADD = $(TESTS_LDADD)
1370 test_integration_fapi_key_create_sign_policy_provision_int_LDFLAGS = $(TESTS_LDFLAGS)
1371 test_integration_fapi_key_create_sign_policy_provision_int_SOURCES = \
1372 test/integration/fapi-key-create-sign-policy-provision.int.c \
1373 test/integration/main-fapi.c test/integration/test-fapi.h
1374
1375 test_integration_fapi_key_create_sign_rsa_int_CFLAGS = $(TESTS_CFLAGS) \
1376 -DFAPI_PROFILE=\"P_RSA\"
1377 test_integration_fapi_key_create_sign_rsa_int_LDADD = $(TESTS_LDADD)
1378 test_integration_fapi_key_create_sign_rsa_int_LDFLAGS = $(TESTS_LDFLAGS)
1379 test_integration_fapi_key_create_sign_rsa_int_SOURCES = \
1380 test/integration/fapi-key-create-sign.int.c \
1381 test/integration/main-fapi.c test/integration/test-fapi.h
1382
1383 test_integration_fapi_key_create_sign_password_int_CFLAGS = $(TESTS_CFLAGS) \
1384 -DFAPI_PASSWORD
1385 test_integration_fapi_key_create_sign_password_int_LDADD = $(TESTS_LDADD)
1386 test_integration_fapi_key_create_sign_password_int_LDFLAGS = $(TESTS_LDFLAGS)
1387 test_integration_fapi_key_create_sign_password_int_SOURCES = \
1388 test/integration/fapi-key-create-sign.int.c \
1389 test/integration/main-fapi.c test/integration/test-fapi.h
1390
1391 test_integration_fapi_key_create_sign_password_da_int_CFLAGS = $(TESTS_CFLAGS) \
1392 -DFAPI_PASSWORD -DFAPI_DA
1393 test_integration_fapi_key_create_sign_password_da_int_LDADD = $(TESTS_LDADD)
1394 test_integration_fapi_key_create_sign_password_da_int_LDFLAGS = $(TESTS_LDFLAGS)
1395 test_integration_fapi_key_create_sign_password_da_int_SOURCES = \
1396 test/integration/fapi-key-create-sign.int.c \
1397 test/integration/main-fapi.c test/integration/test-fapi.h
1398
1399 test_integration_fapi_key_create_sign_persistent_int_CFLAGS = $(TESTS_CFLAGS) \
1400 -DFAPI_PROFILE=\"P_RSA_EK_persistent\" -DFAPI_TEST_EK_CERT_LESS
1401 test_integration_fapi_key_create_sign_persistent_int_LDADD = $(TESTS_LDADD)
1402 test_integration_fapi_key_create_sign_persistent_int_LDFLAGS = $(TESTS_LDFLAGS)
1403 test_integration_fapi_key_create_sign_persistent_int_SOURCES = \
1404 test/integration/fapi-key-create-sign.int.c \
1405 test/integration/main-fapi.c test/integration/test-fapi.h
1406
1407 test_integration_fapi_key_create_policy_authorize_sign_int_CFLAGS = $(TESTS_CFLAGS) -DFAPI_PROFILE=\"P_RSA\"
1408 test_integration_fapi_key_create_policy_authorize_sign_int_LDADD = $(TESTS_LDADD)
1409 test_integration_fapi_key_create_policy_authorize_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1410 test_integration_fapi_key_create_policy_authorize_sign_int_SOURCES = \
1411 test/integration/fapi-key-create-policy-authorize-sign.int.c \
1412 test/integration/main-fapi.c test/integration/test-fapi.h
1413
1414 test_integration_fapi_key_create_policy_authorize_sign_rsa_int_CFLAGS = $(TESTS_CFLAGS) \
1415 -DFAPI_PROFILE=\"P_RSA256\" -DFAPI_TEST_EK_CERT_LESS
1416 test_integration_fapi_key_create_policy_authorize_sign_rsa_int_LDADD = $(TESTS_LDADD)
1417 test_integration_fapi_key_create_policy_authorize_sign_rsa_int_LDFLAGS = $(TESTS_LDFLAGS)
1418 test_integration_fapi_key_create_policy_authorize_sign_rsa_int_SOURCES = \
1419 test/integration/fapi-key-create-policy-authorize-sign.int.c \
1420 test/integration/main-fapi.c test/integration/test-fapi.h
1421
1422 test_integration_fapi_key_create_policy_authorize_nv_sign_int_CFLAGS = $(TESTS_CFLAGS)
1423 test_integration_fapi_key_create_policy_authorize_nv_sign_int_LDADD = $(TESTS_LDADD)
1424 test_integration_fapi_key_create_policy_authorize_nv_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1425 test_integration_fapi_key_create_policy_authorize_nv_sign_int_SOURCES = \
1426 test/integration/fapi-key-create-policy-authorize-nv-sign.int.c \
1427 test/integration/main-fapi.c test/integration/test-fapi.h
1428
1429 test_integration_fapi_key_create_policy_secret_nv_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1430 -DFAPI_PROFILE=\"P_RSA256\" -DFAPI_TEST_EK_CERT_LESS
1431 test_integration_fapi_key_create_policy_secret_nv_sign_int_LDADD = $(TESTS_LDADD)
1432 test_integration_fapi_key_create_policy_secret_nv_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1433 test_integration_fapi_key_create_policy_secret_nv_sign_int_SOURCES = \
1434 test/integration/fapi-key-create-policy-secret-nv-sign.int.c \
1435 test/integration/main-fapi.c test/integration/test-fapi.h
1436
1437 test_integration_fapi_key_create_policy_pcr_sign_int_CFLAGS = $(TESTS_CFLAGS)
1438 test_integration_fapi_key_create_policy_pcr_sign_int_LDADD = $(TESTS_LDADD)
1439 test_integration_fapi_key_create_policy_pcr_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1440 test_integration_fapi_key_create_policy_pcr_sign_int_SOURCES = \
1441 test/integration/fapi-key-create-policy-pcr-sign.int.c \
1442 test/integration/main-fapi.c test/integration/test-fapi.h
1443
1444 test_integration_fapi_key_create_policy_signed_int_CFLAGS = $(TESTS_CFLAGS)
1445 test_integration_fapi_key_create_policy_signed_int_LDADD = $(TESTS_LDADD)
1446 test_integration_fapi_key_create_policy_signed_int_LDFLAGS = $(TESTS_LDFLAGS)
1447 test_integration_fapi_key_create_policy_signed_int_SOURCES = \
1448 test/integration/fapi-key-create-policy-signed.int.c \
1449 test/integration/main-fapi.c test/integration/test-fapi.h
1450
1451 test_integration_fapi_key_create_policy_signed_ecc_int_CFLAGS = $(TESTS_CFLAGS) \
1452 -DTEST_ECC
1453 test_integration_fapi_key_create_policy_signed_ecc_int_LDADD = $(TESTS_LDADD)
1454 test_integration_fapi_key_create_policy_signed_ecc_int_LDFLAGS = $(TESTS_LDFLAGS)
1455 test_integration_fapi_key_create_policy_signed_ecc_int_SOURCES = \
1456 test/integration/fapi-key-create-policy-signed.int.c \
1457 test/integration/main-fapi.c test/integration/test-fapi.h
1458
1459 test_integration_fapi_key_create_policy_nv_sign_int_CFLAGS = $(TESTS_CFLAGS)
1460 test_integration_fapi_key_create_policy_nv_sign_int_LDADD = $(TESTS_LDADD)
1461 test_integration_fapi_key_create_policy_nv_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1462 test_integration_fapi_key_create_policy_nv_sign_int_SOURCES = \
1463 test/integration/fapi-key-create-policy-nv-sign.int.c \
1464 test/integration/main-fapi.c test/integration/test-fapi.h
1465
1466 test_integration_fapi_key_create_policy_or_sign_int_CFLAGS = $(TESTS_CFLAGS)
1467 test_integration_fapi_key_create_policy_or_sign_int_LDADD = $(TESTS_LDADD)
1468 test_integration_fapi_key_create_policy_or_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1469 test_integration_fapi_key_create_policy_or_sign_int_SOURCES = \
1470 test/integration/fapi-key-create-policy-or-sign.int.c \
1471 test/integration/main-fapi.c test/integration/test-fapi.h
1472
1473 test_integration_fapi_key_create_policy_password_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1474 -DTEST_POLICY_PASSWORD -DTEST_PASSWORD
1475 test_integration_fapi_key_create_policy_password_sign_int_LDADD = $(TESTS_LDADD)
1476 test_integration_fapi_key_create_policy_password_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1477 test_integration_fapi_key_create_policy_password_sign_int_SOURCES = \
1478 test/integration/fapi-key-create-policies-sign.int.c \
1479 test/integration/main-fapi.c test/integration/test-fapi.h
1480
1481 test_integration_fapi_key_create_policy_countertimer_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1482 -DTEST_POLICY_COUNTERTIMER
1483 test_integration_fapi_key_create_policy_countertimer_sign_int_LDADD = $(TESTS_LDADD)
1484 test_integration_fapi_key_create_policy_countertimer_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1485 test_integration_fapi_key_create_policy_countertimer_sign_int_SOURCES = \
1486 test/integration/fapi-key-create-policies-sign.int.c \
1487 test/integration/main-fapi.c test/integration/test-fapi.h
1488
1489 test_integration_fapi_key_create_policy_physical_presence_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1490 -DTEST_POLICY_PHYSICAL_PRESENCE
1491 test_integration_fapi_key_create_policy_physical_presence_sign_int_LDADD = $(TESTS_LDADD)
1492 test_integration_fapi_key_create_policy_physical_presence_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1493 test_integration_fapi_key_create_policy_physical_presence_sign_int_SOURCES = \
1494 test/integration/fapi-key-create-policies-sign.int.c \
1495 test/integration/main-fapi.c test/integration/test-fapi.h
1496
1497 test_integration_fapi_key_create_policy_locality_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1498 -DTEST_POLICY_LOCALITY
1499 test_integration_fapi_key_create_policy_locality_sign_int_LDADD = $(TESTS_LDADD)
1500 test_integration_fapi_key_create_policy_locality_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1501 test_integration_fapi_key_create_policy_locality_sign_int_SOURCES = \
1502 test/integration/fapi-key-create-policies-sign.int.c \
1503 test/integration/main-fapi.c test/integration/test-fapi.h
1504
1505 test_integration_fapi_key_create_policy_command_code_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1506 -DTEST_POLICY_COMMAND_CODE
1507 test_integration_fapi_key_create_policy_command_code_sign_int_LDADD = $(TESTS_LDADD)
1508 test_integration_fapi_key_create_policy_command_code_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1509 test_integration_fapi_key_create_policy_command_code_sign_int_SOURCES = \
1510 test/integration/fapi-key-create-policies-sign.int.c \
1511 test/integration/main-fapi.c test/integration/test-fapi.h
1512
1513 test_integration_fapi_key_create_policy_auth_value_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1514 -DTEST_POLICY_AUTH_VALUE -DTEST_PASSWORD
1515 test_integration_fapi_key_create_policy_auth_value_sign_int_LDADD = $(TESTS_LDADD)
1516 test_integration_fapi_key_create_policy_auth_value_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1517 test_integration_fapi_key_create_policy_auth_value_sign_int_SOURCES = \
1518 test/integration/fapi-key-create-policies-sign.int.c \
1519 test/integration/main-fapi.c test/integration/test-fapi.h
1520
1521 test_integration_fapi_key_create_ckda_sign_int_CFLAGS = $(TESTS_CFLAGS) \
1522 -DFAPI_PROFILE=\"P_RSA\"
1523 test_integration_fapi_key_create_ckda_sign_int_LDADD = $(TESTS_LDADD)
1524 test_integration_fapi_key_create_ckda_sign_int_LDFLAGS = $(TESTS_LDFLAGS)
1525 test_integration_fapi_key_create_ckda_sign_int_SOURCES = \
1526 test/integration/fapi-key-create-ckda-sign.int.c \
1527 test/integration/main-fapi.c test/integration/test-fapi.h
1528
1529 test_integration_fapi_key_create_ckda_sign_password_int_CFLAGS = $(TESTS_CFLAGS) \
1530 -DFAPI_PASSWORD -DFAPI_PROFILE=\"P_RSA\"
1531 test_integration_fapi_key_create_ckda_sign_password_int_LDADD = $(TESTS_LDADD)
1532 test_integration_fapi_key_create_ckda_sign_password_int_LDFLAGS = $(TESTS_LDFLAGS)
1533 test_integration_fapi_key_create_ckda_sign_password_int_SOURCES = \
1534 test/integration/fapi-key-create-ckda-sign.int.c \
1535 test/integration/main-fapi.c test/integration/test-fapi.h
1536
1537 test_integration_fapi_key_create_ckda_sign_password_da_int_CFLAGS = $(TESTS_CFLAGS) \
1538 -DFAPI_PASSWORD -DFAPI_DA -DFAPI_PROFILE=\"P_RSA\"
1539 test_integration_fapi_key_create_ckda_sign_password_da_int_LDADD = $(TESTS_LDADD)
1540 test_integration_fapi_key_create_ckda_sign_password_da_int_LDFLAGS = $(TESTS_LDFLAGS)
1541 test_integration_fapi_key_create_ckda_sign_password_da_int_SOURCES = \
1542 test/integration/fapi-key-create-ckda-sign.int.c \
1543 test/integration/main-fapi.c test/integration/test-fapi.h
1544
1545 test_integration_fapi_key_change_auth_int_CFLAGS = $(TESTS_CFLAGS)
1546 test_integration_fapi_key_change_auth_int_LDADD = $(TESTS_LDADD)
1547 test_integration_fapi_key_change_auth_int_LDFLAGS = $(TESTS_LDFLAGS)
1548 test_integration_fapi_key_change_auth_int_SOURCES = \
1549 test/integration/fapi-key-change-auth.int.c \
1550 test/integration/main-fapi.c test/integration/test-fapi.h
1551
1552 test_integration_fapi_nv_ordinary_int_CFLAGS = $(TESTS_CFLAGS)
1553 test_integration_fapi_nv_ordinary_int_LDADD = $(TESTS_LDADD)
1554 test_integration_fapi_nv_ordinary_int_LDFLAGS = $(TESTS_LDFLAGS)
1555 test_integration_fapi_nv_ordinary_int_SOURCES = \
1556 test/integration/fapi-nv-ordinary.int.c \
1557 test/integration/main-fapi.c test/integration/test-fapi.h
1558
1559 test_integration_fapi_nv_authorizenv_cphash_int_CFLAGS = $(TESTS_CFLAGS)
1560 test_integration_fapi_nv_authorizenv_cphash_int_LDADD = $(TESTS_LDADD)
1561 test_integration_fapi_nv_authorizenv_cphash_int_LDFLAGS = $(TESTS_LDFLAGS)
1562 test_integration_fapi_nv_authorizenv_cphash_int_SOURCES = \
1563 test/integration/fapi-nv-authorizenv-cphash.int.c \
1564 test/integration/main-fapi.c test/integration/test-fapi.h
1565
1566 test_integration_fapi_nv_extend_int_CFLAGS = $(TESTS_CFLAGS)
1567 test_integration_fapi_nv_extend_int_LDADD = $(TESTS_LDADD)
1568 test_integration_fapi_nv_extend_int_LDFLAGS = $(TESTS_LDFLAGS)
1569 test_integration_fapi_nv_extend_int_SOURCES = \
1570 test/integration/fapi-nv-extend.int.c \
1571 test/integration/main-fapi.c test/integration/test-fapi.h
1572
1573 test_integration_fapi_nv_increment_int_CFLAGS = $(TESTS_CFLAGS)
1574 test_integration_fapi_nv_increment_int_LDADD = $(TESTS_LDADD)
1575 test_integration_fapi_nv_increment_int_LDFLAGS = $(TESTS_LDFLAGS)
1576 test_integration_fapi_nv_increment_int_SOURCES = \
1577 test/integration/fapi-nv-increment.int.c \
1578 test/integration/main-fapi.c test/integration/test-fapi.h
1579
1580 test_integration_fapi_nv_set_bits_int_CFLAGS = $(TESTS_CFLAGS)
1581 test_integration_fapi_nv_set_bits_int_LDADD = $(TESTS_LDADD)
1582 test_integration_fapi_nv_set_bits_int_LDFLAGS = $(TESTS_LDFLAGS)
1583 test_integration_fapi_nv_set_bits_int_SOURCES = \
1584 test/integration/fapi-nv-set-bits.int.c \
1585 test/integration/main-fapi.c test/integration/test-fapi.h
1586
1587 test_integration_fapi_nv_written_policy_int_CFLAGS = $(TESTS_CFLAGS)
1588 test_integration_fapi_nv_written_policy_int_LDADD = $(TESTS_LDADD)
1589 test_integration_fapi_nv_written_policy_int_LDFLAGS = $(TESTS_LDFLAGS)
1590 test_integration_fapi_nv_written_policy_int_SOURCES = \
1591 test/integration/fapi-nv-written-policy.int.c \
1592 test/integration/main-fapi.c test/integration/test-fapi.h
1593
1594 test_integration_fapi_ext_public_key_int_CFLAGS = $(TESTS_CFLAGS) \
1595 -DFAPI_NONTPM
1596 test_integration_fapi_ext_public_key_int_LDADD = $(TESTS_LDADD)
1597 test_integration_fapi_ext_public_key_int_LDFLAGS = $(TESTS_LDFLAGS)
1598 test_integration_fapi_ext_public_key_int_SOURCES = \
1599 test/integration/fapi-ext-public-key.int.c \
1600 test/integration/main-fapi.c test/integration/test-fapi.h
1601
1602 test_integration_fapi_data_crypt_int_CFLAGS = $(TESTS_CFLAGS)
1603 test_integration_fapi_data_crypt_int_LDADD = $(TESTS_LDADD)
1604 test_integration_fapi_data_crypt_int_LDFLAGS = $(TESTS_LDFLAGS)
1605 test_integration_fapi_data_crypt_int_SOURCES = \
1606 test/integration/fapi-data-crypt.int.c \
1607 test/integration/main-fapi.c test/integration/test-fapi.h
1608
1609 test_integration_fapi_data_crypt_rsa_int_CFLAGS = $(TESTS_CFLAGS) \
1610 -DFAPI_PROFILE=\"P_RSA\"
1611 test_integration_fapi_data_crypt_rsa_int_LDADD = $(TESTS_LDADD)
1612 test_integration_fapi_data_crypt_rsa_int_LDFLAGS = $(TESTS_LDFLAGS)
1613 test_integration_fapi_data_crypt_rsa_int_SOURCES = \
1614 test/integration/fapi-data-crypt.int.c \
1615 test/integration/main-fapi.c test/integration/test-fapi.h
1616
1617 test_integration_fapi_duplicate_int_CFLAGS = $(TESTS_CFLAGS)
1618 test_integration_fapi_duplicate_int_LDADD = $(TESTS_LDADD)
1619 test_integration_fapi_duplicate_int_LDFLAGS = $(TESTS_LDFLAGS)
1620 test_integration_fapi_duplicate_int_SOURCES = \
1621 test/integration/fapi-duplicate.int.c \
1622 test/integration/main-fapi.c test/integration/test-fapi.h
1623
1624
1625 test_integration_fapi_pcr_test_int_CFLAGS = $(TESTS_CFLAGS)
1626 test_integration_fapi_pcr_test_int_LDADD = $(TESTS_LDADD)
1627 test_integration_fapi_pcr_test_int_LDFLAGS = $(TESTS_LDFLAGS)
1628 test_integration_fapi_pcr_test_int_SOURCES = \
1629 test/integration/fapi-pcr-test.int.c \
1630 test/integration/main-fapi.c test/integration/test-fapi.h
1631
1632 test_integration_fapi_quote_int_CFLAGS = $(TESTS_CFLAGS)
1633 test_integration_fapi_quote_int_LDADD = $(TESTS_LDADD)
1634 test_integration_fapi_quote_int_LDFLAGS = $(TESTS_LDFLAGS) -ljson-c
1635 test_integration_fapi_quote_int_SOURCES = \
1636 test/integration/fapi-quote.int.c \
1637 test/integration/main-fapi.c test/integration/test-fapi.h
1638
1639 test_integration_fapi_quote_rsa_int_CFLAGS = $(TESTS_CFLAGS) \
1640 -DFAPI_PROFILE=\"P_RSA\"
1641 test_integration_fapi_quote_rsa_int_LDADD = $(TESTS_LDADD)
1642 test_integration_fapi_quote_rsa_int_LDFLAGS = $(TESTS_LDFLAGS) -ljson-c
1643 test_integration_fapi_quote_rsa_int_SOURCES = \
1644 test/integration/fapi-quote.int.c \
1645 test/integration/main-fapi.c test/integration/test-fapi.h
1646
1647
1648 test_integration_fapi_info_int_CFLAGS = $(TESTS_CFLAGS)
1649 test_integration_fapi_info_int_LDADD = $(TESTS_LDADD)
1650 test_integration_fapi_info_int_LDFLAGS = $(TESTS_LDFLAGS)
1651 test_integration_fapi_info_int_SOURCES = \
1652 test/integration/fapi-info.int.c \
1653 test/integration/main-fapi.c test/integration/test-fapi.h
1654
1655 test_integration_fapi_unseal_int_CFLAGS = $(TESTS_CFLAGS)
1656 test_integration_fapi_unseal_int_LDADD = $(TESTS_LDADD)
1657 test_integration_fapi_unseal_int_LDFLAGS = $(TESTS_LDFLAGS)
1658 test_integration_fapi_unseal_int_SOURCES = \
1659 test/integration/fapi-unseal.int.c \
1660 test/integration/main-fapi.c test/integration/test-fapi.h
1661
1662 test_integration_fapi_provision_fingerprint_int_CFLAGS = $(TESTS_CFLAGS) \
1663 -DFAPI_TEST_FINGERPRINT -DFAPI_PROFILE=\"P_RSA\"
1664 test_integration_fapi_provision_fingerprint_int_LDADD = $(TESTS_LDADD)
1665 test_integration_fapi_provision_fingerprint_int_LDFLAGS = $(TESTS_LDFLAGS)
1666 test_integration_fapi_provision_fingerprint_int_SOURCES = \
1667 test/integration/fapi-get-random.int.c \
1668 test/integration/main-fapi.c test/integration/test-fapi.h
1669
1670 test_integration_fapi_provision_certificate_int_CFLAGS = $(TESTS_CFLAGS) \
1671 -DFAPI_TEST_CERTIFICATE -DFAPI_PROFILE=\"P_RSA\"
1672 test_integration_fapi_provision_certificate_int_LDADD = $(TESTS_LDADD)
1673 test_integration_fapi_provision_certificate_int_LDFLAGS = $(TESTS_LDFLAGS)
1674 test_integration_fapi_provision_certificate_int_SOURCES = \
1675 test/integration/fapi-get-random.int.c \
1676 test/integration/main-fapi.c test/integration/test-fapi.h
1677
1678 test_integration_fapi_provision_fingerprint_ecc_int_CFLAGS = $(TESTS_CFLAGS) \
1679 -DFAPI_TEST_FINGERPRINT_ECC -DFAPI_PROFILE=\"P_ECC\"
1680 test_integration_fapi_provision_fingerprint_ecc_int_LDADD = $(TESTS_LDADD)
1681 test_integration_fapi_provision_fingerprint_ecc_int_LDFLAGS = $(TESTS_LDFLAGS)
1682 test_integration_fapi_provision_fingerprint_ecc_int_SOURCES = \
1683 test/integration/fapi-get-random.int.c \
1684 test/integration/main-fapi.c test/integration/test-fapi.h
1685
1686 test_integration_fapi_provision_certificate_ecc_int_CFLAGS = $(TESTS_CFLAGS) \
1687 -DFAPI_TEST_CERTIFICATE_ECC -DFAPI_PROFILE=\"P_ECC\"
1688 test_integration_fapi_provision_certificate_ecc_int_LDADD = $(TESTS_LDADD)
1689 test_integration_fapi_provision_certificate_ecc_int_LDFLAGS = $(TESTS_LDFLAGS)
1690 test_integration_fapi_provision_certificate_ecc_int_SOURCES = \
1691 test/integration/fapi-get-random.int.c \
1692 test/integration/main-fapi.c test/integration/test-fapi.h
1693
1694 endif #FAPI
1695
11891696 endif #ENABLE_INTEGRATION
11901697
11911698 check-ptpm:
77 ### Initialize global variables used throughout the file ###
88 INCLUDE_DIRS = -I$(srcdir)/src -I$(srcdir)/include/tss2
99 ACLOCAL_AMFLAGS = -I m4 --install
10 AM_CFLAGS = $(INCLUDE_DIRS) $(EXTRA_CFLAGS) $(CODE_COVERAGE_CFLAGS)
11 AM_LDFLAGS = $(EXTRA_LDFLAGS) $(CODE_COVERAGE_LIBS)
10 AM_CFLAGS = $(INCLUDE_DIRS) $(EXTRA_CFLAGS) $(CODE_COVERAGE_CFLAGS) \
11 $(SANITIZER_CFLAGS)
12 AM_LDFLAGS = $(EXTRA_LDFLAGS) $(CODE_COVERAGE_LIBS) $(SANITIZER_LDFLAGS)
1213
1314 # Initialize empty variables to be extended throughout
1415 lib_LTLIBRARIES =
2223 $(DIST_ARCHIVES) \
2324 AUTHORS
2425
25 GITIGNOREFILES = \
26 TSS_GITIGNOREFILES = \
2627 $(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \
2728 $(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \
2829 $(GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL) \
4748 m4/ax_valgrind_check.m4 \
4849 m4/pkg.m4
4950
51 GITIGNOREFILES = ""
5052 ### Add ax_* rules ###
5153 # ax_code_coverage
5254 if AUTOCONF_CODE_COVERAGE_2019_01_06
5658 else
5759 @CODE_COVERAGE_RULES@
5860 endif
59 CODE_COVERAGE_DIRECTORY = $(top_builddir)/src
61 GITIGNOREFILES += $(TSS_GITIGNOREFILES)
62 CODE_COVERAGE_DIRECTORY = $(top_builddir)/src $(top_builddir)/test
6063
6164 # ax_valgrind_check
6265 @VALGRIND_CHECK_RULES@
380383 endif # HAVE_LD_VERSION_SCRIPT
381384 src_tss2_rc_libtss2_rc_la_SOURCES = $(TSS2_RC_SRC)
382385
386
387 ### TCG TSS FAPI spec library ###
388 if FAPI
389 fapiconfdir = @sysconfdir@/tpm2-tss
390 fapiconf_DATA = fapi-config.json
391
392 EXTRA_DIST += dist/fapi-config.json.in
393 CLEANFILES += fapi-config.json
394
395 # We have to do this ourselves, in order to get absolute paths
396 fapi-config.json: dist/fapi-config.json.in
397 $(AM_V_GEN) $(SED) \
398 -e 's|[@]prefix@|$(prefix)|g' \
399 -e 's|[@]datarootdir@|$(datarootdir)|g' \
400 -e 's|[@]datadir@|$(datadir)|g' \
401 -e 's|[@]sysconfdir@|$(sysconfdir)|g' \
402 -e 's|[@]sharedstatedir@|$(sharedstatedir)|g' \
403 -e 's|[@]localstatedir@|$(localstatedir)|g' \
404 -e 's|[@]runstatedir@|$(runstatedir)|g' \
405 -e 's|[@]userstatedir@|$(userstatedir)|g' \
406 < "$<" > "$@"
407
408 sysusers_DATA = dist/sysusers.d/tpm2-tss.conf
409 tmpfiles_DATA = tpm2-tss-fapi.conf
410
411 EXTRA_DIST += dist/sysusers.d/tpm2-tss.conf dist/tmpfiles.d/tpm2-tss-fapi.conf.in
412 CLEANFILES += tpm2-tss-fapi.conf
413
414 # We have to do this ourselves, in order to get absolute paths
415 tpm2-tss-fapi.conf: dist/tmpfiles.d/tpm2-tss-fapi.conf.in
416 $(AM_V_GEN) $(SED) \
417 -e 's|[@]localstatedir@|$(localstatedir)|g' \
418 -e 's|[@]runstatedir@|$(runstatedir)|g' \
419 < "$<" > "$@"
420
421 EXTRA_DIST += dist/fapi-profiles/P_RSA2048SHA256.json \
422 dist/fapi-profiles/P_ECCP256SHA256.json
423
424 fapiprofilesdir = @sysconfdir@/tpm2-tss/fapi-profiles
425 fapiprofiles_DATA = dist/fapi-profiles/P_RSA2048SHA256.json \
426 dist/fapi-profiles/P_ECCP256SHA256.json
427
428 libtss2_fapi = src/tss2-fapi/libtss2-fapi.la
429 tss2_HEADERS += $(srcdir)/include/tss2/tss2_fapi.h
430 lib_LTLIBRARIES += $(libtss2_fapi)
431 pkgconfig_DATA += lib/tss2-fapi.pc
432 EXTRA_DIST += \
433 lib/tss2-fapi.map \
434 lib/tss2-fapi.def \
435 test/data/fapi/P_RSA_EK_persistent.json \
436 test/data/fapi/P_RSA.json \
437 test/data/fapi/P_RSA_sh_policy.json \
438 test/data/fapi/P_RSA256.json \
439 test/data/fapi/P_ECC.json \
440 test/data/fapi/policy/pol_pcr16_0.json \
441 test/data/fapi/policy/pol_pcr16_0_fail.json \
442 test/data/fapi/policy/pol_pcr16_0_or.json \
443 test/data/fapi/policy/pol_nv.json \
444 test/data/fapi/policy/pol_nv_written.json \
445 test/data/fapi/policy/pol_signed.json \
446 test/data/fapi/policy/pol_signed_ecc.json \
447 test/data/fapi/policy/pol_authorize.json \
448 test/data/fapi/policy/pol_authorize_outer.json \
449 test/data/fapi/policy/pol_authorize_nv.json \
450 test/data/fapi/policy/pol_secret.json \
451 test/data/fapi/policy/pol_password.json \
452 test/data/fapi/policy/pol_auth_value.json \
453 test/data/fapi/policy/pol_command_code.json \
454 test/data/fapi/policy/pol_locality.json \
455 test/data/fapi/policy/pol_physical_presence.json \
456 test/data/fapi/policy/pol_duplicate.json \
457 test/data/fapi/policy/pol_nv_change_auth.json \
458 test/data/fapi/policy/pol_countertimer.json \
459 test/data/fapi/policy/pol_name_hash.json \
460 test/data/fapi/policy/pol_pcr16_read.json \
461 test/data/fapi/policy/pol_action.json \
462 test/data/fapi/policy/pol_cphash.json
463
464 src_tss2_fapi_libtss2_fapi_la_LIBADD = $(libtss2_sys) $(libtss2_mu) $(libtss2_esys) \
465 $(libutil) $(libtss2_tctildr)
466
467 src_tss2_fapi_libtss2_fapi_la_SOURCES = $(TSS2_FAPI_SRC)
468 src_tss2_fapi_libtss2_fapi_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/tss2-fapi
469 src_tss2_fapi_libtss2_fapi_la_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LIBS) $(JSON_C_LIBS) $(CURL_LIBS)
470 if HAVE_LD_VERSION_SCRIPT
471 src_tss2_fapi_libtss2_fapi_la_LDFLAGS += -Wl,--version-script=$(srcdir)/lib/tss2-fapi.map
472 endif # HAVE_LD_VERSION_SCRIPT
473
474
475 if DOXYMAN
476 DOXYMAN3 += \
477 doxygen-doc/man/Fapi_AuthorizePolicy.3 \
478 doxygen-doc/man/Fapi_ChangeAuth.3 \
479 doxygen-doc/man/Fapi_CreateKey.3 \
480 doxygen-doc/man/Fapi_CreateNv.3 \
481 doxygen-doc/man/Fapi_CreateSeal.3 \
482 doxygen-doc/man/Fapi_Decrypt.3 \
483 doxygen-doc/man/Fapi_Delete.3 \
484 doxygen-doc/man/Fapi_Encrypt.3 \
485 doxygen-doc/man/Fapi_ExportKey.3 \
486 doxygen-doc/man/Fapi_ExportPolicy.3 \
487 doxygen-doc/man/Fapi_Finalize.3 \
488 doxygen-doc/man/Fapi_Free.3 \
489 doxygen-doc/man/Fapi_GetAppData.3 \
490 doxygen-doc/man/Fapi_GetCertificate.3 \
491 doxygen-doc/man/Fapi_GetDescription.3 \
492 doxygen-doc/man/Fapi_GetInfo.3 \
493 doxygen-doc/man/Fapi_GetPlatformCertificates.3 \
494 doxygen-doc/man/Fapi_GetPollHandles.3 \
495 doxygen-doc/man/Fapi_GetRandom.3 \
496 doxygen-doc/man/Fapi_GetTcti.3 \
497 doxygen-doc/man/Fapi_GetTpmBlobs.3 \
498 doxygen-doc/man/Fapi_Import.3 \
499 doxygen-doc/man/Fapi_Initialize.3 \
500 doxygen-doc/man/Fapi_List.3 \
501 doxygen-doc/man/Fapi_NvExtend.3 \
502 doxygen-doc/man/Fapi_NvIncrement.3 \
503 doxygen-doc/man/Fapi_NvRead.3 \
504 doxygen-doc/man/Fapi_NvSetBits.3 \
505 doxygen-doc/man/Fapi_NvWrite.3 \
506 doxygen-doc/man/Fapi_PcrExtend.3 \
507 doxygen-doc/man/Fapi_PcrRead.3 \
508 doxygen-doc/man/Fapi_Provision.3 \
509 doxygen-doc/man/Fapi_Quote.3 \
510 doxygen-doc/man/Fapi_SetAppData.3 \
511 doxygen-doc/man/Fapi_SetAuthCB.3 \
512 doxygen-doc/man/Fapi_SetBranchCB.3 \
513 doxygen-doc/man/Fapi_SetCertificate.3 \
514 doxygen-doc/man/Fapi_SetDescription.3 \
515 doxygen-doc/man/Fapi_SetSignCB.3 \
516 doxygen-doc/man/Fapi_Sign.3 \
517 doxygen-doc/man/FapiTestgroup.3 \
518 doxygen-doc/man/Fapi_Unseal.3 \
519 doxygen-doc/man/Fapi_VerifyQuote.3 \
520 doxygen-doc/man/Fapi_VerifySignature.3 \
521 doxygen-doc/man/Fapi_WriteAuthorizeNv.3
522 endif #DOXYMAN
523
524 endif #FAPI
525
383526 ### Man Pages
384527 man3_MANS = \
385528 man/man3/Tss2_Tcti_Device_Init.3 \
414557 -rm $(DESTDIR)$(udevrulesdir)/$(udevrulesprefix)tpm-udev.rules
415558 endif
416559
560 # Create tss user and FAPI directories directly after installation (vs. after a reboot)
417561 install-exec-hook:
418 cd $(DESTDIR)$(libdir) && \
419 $(LN_S) -f libtss2-tcti-device.so libtss2-tcti-default.so
562 systemd-sysusers && systemd-tmpfiles --create || true
420563
421564 uninstall-hook:
422 cd $(DESTDIR)$(libdir) && \
423 [ -L libtss2-tcti-default.so ] && \
424 rm -f libtss2-tcti-default.so || true
425565 cd $(DESTDIR)$(man3dir) && \
426566 [ -L Tss2_TctiLdr_Initialize_Ex.3 ] && \
427567 rm -f Tss2_TctiLdr_Initialize_Ex.3 || true
00 [![Linux Build Status](https://travis-ci.org/tpm2-software/tpm2-tss.svg?branch=master)](https://travis-ci.org/tpm2-software/tpm2-tss)
11 [![Windows Build status](https://ci.appveyor.com/api/projects/status/2rdmyn1ndkiavngn?svg=true)](https://ci.appveyor.com/project/tpm2-software/tpm2-tss)
2 [![FreeBSD Build status](https://api.cirrus-ci.com/github/tpm2-software/tpm2-tss.svg?branch=master)](https://cirrus-ci.com/github/tpm2-software/tpm2-tss)
23 [![Coverity Scan](https://img.shields.io/coverity/scan/3997.svg)](https://scan.coverity.com/projects/tpm2-tss)
34 [![Coverage Status](https://codecov.io/gh/tpm2-software/tpm2-tss/branch/master/graph/badge.svg)](https://codecov.io/gh/tpm2-software/tpm2-tss)
45 [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2332/badge)](https://bestpractices.coreinfrastructure.org/projects/2332)
56 [![Total alerts](https://img.shields.io/lgtm/alerts/g/tpm2-software/tpm2-tss.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/tpm2-software/tpm2-tss/alerts/)
67 [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/tpm2-software/tpm2-tss.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/tpm2-software/tpm2-tss/context:cpp)
8 [![Documentation Status](https://readthedocs.org/projects/tpm2-tss/badge/?version=latest)](https://tpm2-tss.readthedocs.io/en/latest/?badge=latest)
9 [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/tpm2-tss.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:tpm2-tss)
10 [![Gitter](https://badges.gitter.im/tpm2-software/community.svg)](https://gitter.im/tpm2-software/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
711
812 # Overview
913 This repository hosts source code implementing the Trusted Computing Group's (TCG) TPM2 Software Stack (TSS).
1014 This stack consists of the following layers from top to bottom:
1115
16 * Feature API (FAPI) as described in the [TSS 2.0 Feature API Specification](https://trustedcomputinggroup.org/wp-content/uploads/TSS_FAPI_v0.94_r04_pubrev.pdf)
17 along with [TSS 2.0 JSON Data Types and Policy Language Specification](https://trustedcomputinggroup.org/wp-content/uploads/TSS_JSON_Policy_v0.7_r04_pubrev.pdf)
18 This API is designed to be very high-level API, intended to make programming with the TPM as simple as possible.
19 The API functions are exposed through a single library: libtss2-fapi.
1220 * Enhanced System API (ESAPI) as described in the [TSS 2.0 Enhanced System API (ESAPI) Specification](https://trustedcomputinggroup.org/wp-content/uploads/TSS_ESAPI_Version-0.9_Revision-04_reviewEND030918.pdf).
1321 This API is a 1-to-1 mapping of the TPM2 commands documented in Part 3 of the TPM2 specification.
1422 Additionally there are asynchronous versions of each command.
3442 Instructions to build and install tpm2-tss are available in the [INSTALL](INSTALL.md) file.
3543
3644 # Getting in Touch:
37 If you're looking to discuss the source code in this project or get some questions answered you should join the 01.org TPM2 mailing list: https://lists.01.org/mailman/listinfo/tpm2.
45 If you're looking to discuss the source code in this project or get some questions answered you should join the 01.org TPM2 mailing list: https://lists.01.org/postorius/lists/tpm2.lists.01.org/.
3846 We also have an IRC channel set up on [FreeNode](https://freenode.net/) called \#tpm2.0-tss.
47 You can also try Gitter [![Gitter](https://badges.gitter.im/tpm2-software/community.svg)](https://gitter.im/tpm2-software/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
3948
4049 In case you want to contribute to the project, please also have a look at the [Contribution Guidelines](CONTRIBUTING.md).
50
51 # Documentation
52
53 The doxygen documentation can either be built by oneself (see the [INSTALL](INSTALL.md) file) or browsed directly on [tpm2-tss.readthedocs.io](https://tpm2-tss.readthedocs.io/).
4154
4255 # Test Suite
4356 This repository contains a test suite intended to exercise the TCTI, SAPI and ESAPI code.
171184 ![Architecture Block Diagram](doc/TSS_block_diagram.png)
172185
173186 # Project Layout
187 ```
174188 ├── doc : various bits of documentation\
175189 ├── include : header files installed in $(includedir)\
176190 │ └── tss2 : all public headers for this project\
190204    ├── integration : integration test harness and test cases\
191205    ├── tpmclient : monolithic, legacy test application\
192206    └── unit : unit tests
207 ```
5555 **NOTE** release candidates must be taken down after a release with the corresponding version number is available.
5656
5757 ## Signing Release Tarballs
58 Signatures must be generated using the `--detach-sign` and `--armor` options to the `gpg` command.
58 Signatures must be generated using the `--detach-sign` and `--armor` options to the `gpg` command:
59 ```
60 $ gpg --detach-sign --armor tpm2-tss-X.Y.Z.tar.gz
61 ```
5962
6063 ## Verifying Signatures
6164 Verifying the signature on a release tarball requires the project maintainers public keys be installed in the GPG keyring of the verifier.
7275 * be associated with the maintainers github account (https://help.github.com/articles/adding-a-new-gpg-key-to-your-github-account/)
7376
7477 # Announcements
75 Release candidates and proper releases should be announced on the 01.org TPM2 mailing list: https://lists.01.org/mailman/listinfo/tpm2.
78 Release candidates and proper releases should be announced on the 01.org TPM2 mailing list: https://lists.01.org/postorius/lists/tpm2.lists.01.org/.
7679 This announcement should be accompanied by a link to the release page on Github as well as a link to the CHANGELOG.md accompanying the release.
7780
7881 # Maintainance
5757 src_esys_listvar "src/tss2-esys/" "*.c" "TSS2_ESYS_C" src/tss2-esys/esys_crypto_ossl.c src/tss2-esys/esys_crypto_gcrypt.c
5858 printf "TSS2_ESYS_SRC = \$(TSS2_ESYS_H) \$(TSS2_ESYS_C)\n"
5959
60 src_listvar "src/tss2-fapi/" "*.h" "TSS2_FAPI_H"
61 src_listvar "src/tss2-fapi/" "*.c" "TSS2_FAPI_C"
62 printf "TSS2_FAPI_SRC = \$(TSS2_FAPI_H) \$(TSS2_FAPI_C)\n"
63
6064 src_listvar "src/tss2-mu" "*.c" "TSS2_MU_C"
6165 src_listvar "src/tss2-mu" "*.h" "TSS2_MU_H"
6266 printf "TSS2_MU_SRC = \$(TSS2_MU_C) \$(TSS2_MU_H)\n"
6771 ) > ${VARS_FILE}
6872
6973 # Do not generate fuzz tests unless environment variable GEN_FUZZ is set to 1
74 rm -rf Makefile-fuzz-generated.am
7075 if test "${GEN_FUZZ}0" -eq 10; then
7176 echo "Generating fuzz tests"
7277 script/gen_fuzz.py
33 # All rights reserved.
44
55 AC_INIT([tpm2-tss],
6 [2.3.3],
6 [2.4.0],
77 [https://github.com/tpm2-software/tpm2-tss/issues],
88 [],
99 [https://github.com/tpm2-software/tpm2-tss])
1414
1515 AC_CONFIG_HEADERS([config.h])
1616
17 AC_CONFIG_FILES([Makefile Doxyfile lib/tss2-sys.pc lib/tss2-esys.pc lib/tss2-mu.pc lib/tss2-tcti-device.pc lib/tss2-tcti-mssim.pc lib/tss2-rc.pc lib/tss2-tctildr.pc])
17 AC_CONFIG_FILES([Makefile Doxyfile lib/tss2-sys.pc lib/tss2-esys.pc lib/tss2-mu.pc lib/tss2-tcti-device.pc lib/tss2-tcti-mssim.pc lib/tss2-rc.pc lib/tss2-tctildr.pc lib/tss2-fapi.pc])
1818
1919 # propagate configure arguments to distcheck
2020 AC_SUBST([DISTCHECK_CONFIGURE_FLAGS],[$ac_configure_args])
2424 AX_IS_RELEASE(dash-version)
2525 AX_CHECK_ENABLE_DEBUG([info])
2626
27 AC_PROG_CC
2728 AC_PROG_CXX
28 AC_PROG_CC
2929 AC_PROG_LN_S
3030 AC_USE_SYSTEM_EXTENSIONS
3131 LT_INIT()
3535 # Check OS and set library and compile flags accordingly
3636 case "${host_os}" in
3737 *nto-qnx*)
38 HOSTOS='QNX'
3839 ADD_COMPILER_FLAG([-D_QNX_SOURCE])
3940 LIBSOCKET_LDFLAGS="-lsocket"
4041 ;;
42 *bsd* | *BSD*)
43 HOSTOS='BSD'
44 LIBSOCKET_LDFLAGS=""
45 ;;
4146 *)
47 #Assume linux
48 HOSTOS='Linux'
4249 LIBSOCKET_LDFLAGS=""
4350 ;;
4451 esac
4552 AC_SUBST([LIBSOCKET_LDFLAGS])
46
47 AC_CHECK_FUNCS([strndup])
53 AC_SUBST([HOSTOS])
54
55 # runstatedir is only defined in the yet unreleased Autoconf 2.70
56 AC_ARG_WITH([runstatedir],
57 AS_HELP_STRING([--with-runstatedir=<dir>],
58 [replacement for --runstatedir in Autoconf <2.70]),
59 [runstatedir="$withval"])
60 AS_IF([test -z "$runstatedir"], [runstatedir="${localstatedir}/run"])
61 AC_SUBST([runstatedir])
62
63 AX_RECURSIVE_EVAL([$sysconfdir], [SYSCONFDIR])
64 AC_DEFINE_UNQUOTED([SYSCONFDIR], ["$SYSCONFDIR"], [System config dir])
65
66 AC_ARG_WITH([userstatedir],
67 [AS_HELP_STRING([--with-userstatedir=<dir>],
68 [sets the relative path in the user's home (default is ".local/share")])],,
69 [with_userstatedir=.local/share])
70 AC_SUBST(userstatedir, $with_userstatedir)
71
72 AC_ARG_WITH([sysusersdir],
73 [AS_HELP_STRING([--with-sysusersdir=<dir>],
74 [sets the sysusers.d directory (default is "${sysconfdir}/sysusers.d")])],,
75 [with_sysusersdir="${sysconfdir}/sysusers.d"])
76 AC_SUBST(sysusersdir, $with_sysusersdir)
77
78 AC_ARG_WITH([tmpfilesdir],
79 [AS_HELP_STRING([--with-tmpfilesdir=<dir>],
80 [sets the tmpfiles.d directory (default is "${sysconfdir}/tmpfiles.d")])],,
81 [with_tmpfilesdir="${sysconfdir}/tmpfiles.d"])
82 AC_SUBST(tmpfilesdir, $with_tmpfilesdir)
83
4884 AC_ARG_ENABLE([unit],
4985 [AS_HELP_STRING([--enable-unit],
5086 [build cmocka unit tests])],,
64100
65101 AM_CONDITIONAL(ESAPI, test "x$enable_esapi" = "xyes")
66102
103 AC_CHECK_FUNC([strndup],[],[AC_MSG_ERROR([strndup function not found])])
104 AC_CHECK_FUNCS([reallocarray])
105 AC_ARG_ENABLE([fapi],
106 [AS_HELP_STRING([--enable-fapi],
107 [build the fapi layer (default is yes)])],
108 [enable_fapi=$enableval],
109 [enable_fapi=yes])
110
111 AM_CONDITIONAL(FAPI, test "x$enable_fapi" = "xyes")
112
113 AC_ARG_ENABLE([fapi-async-tests],
114 AS_HELP_STRING([--enable-fapi-async-tests],
115 [Force fapi to spin asynchronously. (NOT FOR PRODUCTION!)]),,
116 [enable_fapi_async_tests=no])
117 AS_IF([test "x$enable_fapi_async_tests" = "xyes"],
118 AC_DEFINE([TEST_FAPI_ASYNC], [1], [FAPI forced async spinning]))
119 AS_IF([test "x$enable_fapi_async_tests" = "xyes"],
120 AC_MSG_WARN("FAPI compiled with asynchronous spinning testing. NOT FOR PRODUCTION!"))
121
67122 AC_ARG_ENABLE([tcti-device-async],
68123 AS_HELP_STRING([--enable-tcti-device-async],
69124 [Enable asynchronus operation on TCTI device
90145
91146 AS_IF([test "x$enable_esapi" = xyes],
92147 [AS_IF([test "x$with_crypto" = xgcrypt], [
93 AC_CHECK_HEADER([gcrypt.h],,
94 [AC_MSG_ERROR([Missing required header: gcrypt.h.])])
95 AC_CHECK_LIB([gcrypt],
96 [gcry_mac_open],,
97 [AC_MSG_ERROR([Missing required library: gcrypt.])])
98 TSS2_ESYS_CFLAGS_CRYPTO=""
99 TSS2_ESYS_LDFLAGS_CRYPTO="-lgcrypt"
148 AM_PATH_LIBGCRYPT([1.6.0], [], [AC_MSG_ERROR([Missing required gcrypt library])])
149 TSS2_ESYS_CFLAGS_CRYPTO="$LIBGCRYPT_CFLAGS"
150 TSS2_ESYS_LDFLAGS_CRYPTO="$LIBGCRYPT_LIBS"
100151 ], [test "x$with_crypto" = xossl], [
101152 PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto])
102153 AC_DEFINE([OSSL], [1], [OpenSSL cryptographic backend])
105156 ], AC_MSG_ERROR([Bad value for --with-crypto $with_crypto]))])
106157 AC_SUBST([TSS2_ESYS_CFLAGS_CRYPTO])
107158 AC_SUBST([TSS2_ESYS_LDFLAGS_CRYPTO])
159
160 AS_IF([test "x$enable_fapi" != xno -a "x$enable_esapi" = "xno"],
161 AC_MSG_ERROR([ESAPI has to be enabled to compile FAPI.]))
162
163 AS_IF([test "x$enable_fapi" != xno -a "x$with_crypto" != "xossl"],
164 AC_MSG_ERROR([FAPI has to be compiled with OpenSSL]))
165
166 AS_IF([test "x$enable_fapi" = xyes ],
167 PKG_CHECK_MODULES([JSON_C], [json-c]))
168
169 AS_IF([test "x$enable_fapi" = xyes ],
170 PKG_CHECK_MODULES([CURL], [libcurl]))
108171
109172 AC_ARG_WITH([tctidefaultmodule],
110173 [AS_HELP_STRING([--with-tctidefaultmodule],
173236 [AS_HELP_STRING([--enable-integration],
174237 [build and execute integration tests])],,
175238 [enable_integration=no])
176 AS_IF([test "x$enable_integration" = "xyes"],
239 AS_IF([test "x$enable_integration" = "xyes" -a "$HOSTOS" = "Linux"],
177240 [ERROR_IF_NO_PROG([tpm_server])
178241 ERROR_IF_NO_PROG([ss])
179242 ERROR_IF_NO_PROG([ps])
199262 AC_MSG_ERROR([Integration tests can not be enabled without the TCTI_MSSIM module]))
200263 AC_SUBST([ENABLE_INTEGRATION], [$enable_integration])])
201264 AM_CONDITIONAL([ENABLE_INTEGRATION],[test "x$enable_integration" = "xyes"])
265 #
266 # sanitizer compiler flags
267 #
268 AC_ARG_WITH([sanitizer],
269 [AS_HELP_STRING([--with-sanitizer={none,address,undefined}],
270 [build with the given sanitizer])],,
271 [with_sanitizer=none])
272 AS_CASE(["x$with_sanitizer"],
273 ["xnone"],
274 [],
275 ["xaddress"],
276 [
277 SANITIZER_CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
278 SANITIZER_LDFLAGS="-lasan"
279 ],
280 ["xundefined"],
281 [
282 SANITIZER_CFLAGS="-fsanitize=undefined"
283 SANITIZER_LDFLAGS="-lubsan"
284 ],
285 [AC_MSG_ERROR([Bad value for --with-sanitizer])])
286 AC_SUBST([SANITIZER_CFLAGS])
287 AC_SUBST([SANITIZER_LDFLAGS])
202288 #
203289 # fuzz testing
204290 #
363449 AC_MSG_RESULT([
364450 $PACKAGE_NAME $VERSION
365451 esapi: $enable_esapi
452 fapi: $enable_fapi
366453 tctidefaultmodule: $with_tctidefaultmodule
367454 tctidefaultconfig: $with_tctidefaultconfig
368455 unit: $enable_unit
373460 tcti-device-async: $enable_tcti_device_async
374461 tcti-partial-read: $enable_tcti_partial_reads
375462 crypto backend: $with_crypto
463 sysconfdir: $sysconfdir
464 localstatedir: $localstatedir
465 runstatedir: $runstatedir
466 sysusersdir: $sysusersdir
467 tmpfilesdir: $tmpfilesdir
468 userstatedir: [\$HOME/]$with_userstatedir
376469 ])
0 tpm2-tss (2.4.0-1) unstable; urgency=low
1
2 [ Ying-Chun Liu (PaulLiu) <paulliu@debian.org> ]
3 * New upstream release
4
5 -- Ying-Chun Liu (PaulLiu) <paulliu@debian.org> Sun, 22 Mar 2020 23:59:21 +0800
6
07 tpm2-tss (2.3.3-1) unstable; urgency=low
18
29 [ Ying-Chun Liu (PaulLiu) <paulliu@debian.org> ]
33 Maintainer: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
44 Uploaders: Ying-Chun Liu (PaulLiu) <paulliu@debian.org>,
55 Ivan Hu <ivan.hu@ubuntu.com>,
6 Mario Limonciello <superm1@gmail.com>
6 Mario Limonciello <superm1@gmail.com>
77 Build-Depends: autoconf,
88 autoconf-archive,
99 debhelper (>= 11),
1010 docbook-xsl,
1111 doxygen,
1212 libcmocka-dev (>= 1.0),
13 libcurl4-openssl-dev | libcurl-dev,
1314 libgcrypt20-dev,
15 libjson-c-dev,
1416 libltdl-dev,
1517 libssl-dev,
1618 libtool,
0 Document: tpm2-tss
1 Title: tpm2-tss Documentation
2 Author: Intel Corporation
3 Abstract: This manual describes TPM Software stack 2.0 TCG spec compliant
4 implementation.
5 Section: System/Security
6
7 Format: HTML
8 Index: /usr/share/doc/libtss2-dev/html/index.html
9 Files: /usr/share/doc/libtss2-dev/html/*.html
0 doxygen-doc/html
0 usr/share/man/man3
103103 Esys_GetSessionAuditDigest@Base 2.3.1
104104 Esys_GetSessionAuditDigest_Async@Base 2.3.1
105105 Esys_GetSessionAuditDigest_Finish@Base 2.3.1
106 Esys_GetSysContext@Base 2.4.0
106107 Esys_GetTcti@Base 2.3.1
107108 Esys_GetTestResult@Base 2.3.1
108109 Esys_GetTestResult_Async@Base 2.3.1
329330 Esys_StirRandom_Async@Base 2.3.1
330331 Esys_StirRandom_Finish@Base 2.3.1
331332 Esys_TRSess_GetAttributes@Base 2.3.1
333 Esys_TRSess_GetAuthRequired@Base 2.4.0
332334 Esys_TRSess_GetNonceTPM@Base 2.3.1
333335 Esys_TRSess_SetAttributes@Base 2.3.1
334336 Esys_TR_Close@Base 2.3.1
337339 Esys_TR_FromTPMPublic_Async@Base 2.3.1
338340 Esys_TR_FromTPMPublic_Finish@Base 2.3.1
339341 Esys_TR_GetName@Base 2.3.1
342 Esys_TR_GetTpmHandle@Base 2.4.0
340343 Esys_TR_Serialize@Base 2.3.1
341344 Esys_TR_SetAuth@Base 2.3.1
342345 Esys_TestParms@Base 2.3.1
354357 Esys_ZGen_2Phase@Base 2.3.1
355358 Esys_ZGen_2Phase_Async@Base 2.3.1
356359 Esys_ZGen_2Phase_Finish@Base 2.3.1
360 libtss2-fapi.so.0 libtss2-esys0 #MINVER#
361 Fapi_AuthorizePolicy@Base 2.4.0
362 Fapi_AuthorizePolicy_Async@Base 2.4.0
363 Fapi_AuthorizePolicy_Finish@Base 2.4.0
364 Fapi_ChangeAuth@Base 2.4.0
365 Fapi_ChangeAuth_Async@Base 2.4.0
366 Fapi_ChangeAuth_Finish@Base 2.4.0
367 Fapi_CreateKey@Base 2.4.0
368 Fapi_CreateKey_Async@Base 2.4.0
369 Fapi_CreateKey_Finish@Base 2.4.0
370 Fapi_CreateNv@Base 2.4.0
371 Fapi_CreateNv_Async@Base 2.4.0
372 Fapi_CreateNv_Finish@Base 2.4.0
373 Fapi_CreateSeal@Base 2.4.0
374 Fapi_CreateSeal_Async@Base 2.4.0
375 Fapi_CreateSeal_Finish@Base 2.4.0
376 Fapi_Decrypt@Base 2.4.0
377 Fapi_Decrypt_Async@Base 2.4.0
378 Fapi_Decrypt_Finish@Base 2.4.0
379 Fapi_Delete@Base 2.4.0
380 Fapi_Delete_Async@Base 2.4.0
381 Fapi_Delete_Finish@Base 2.4.0
382 Fapi_Encrypt@Base 2.4.0
383 Fapi_Encrypt_Async@Base 2.4.0
384 Fapi_Encrypt_Finish@Base 2.4.0
385 Fapi_ExportKey@Base 2.4.0
386 Fapi_ExportKey_Async@Base 2.4.0
387 Fapi_ExportKey_Finish@Base 2.4.0
388 Fapi_ExportPolicy@Base 2.4.0
389 Fapi_ExportPolicy_Async@Base 2.4.0
390 Fapi_ExportPolicy_Finish@Base 2.4.0
391 Fapi_Finalize@Base 2.4.0
392 Fapi_Free@Base 2.4.0
393 Fapi_GetAppData@Base 2.4.0
394 Fapi_GetAppData_Async@Base 2.4.0
395 Fapi_GetAppData_Finish@Base 2.4.0
396 Fapi_GetCertificate@Base 2.4.0
397 Fapi_GetCertificate_Async@Base 2.4.0
398 Fapi_GetCertificate_Finish@Base 2.4.0
399 Fapi_GetDescription@Base 2.4.0
400 Fapi_GetDescription_Async@Base 2.4.0
401 Fapi_GetDescription_Finish@Base 2.4.0
402 Fapi_GetInfo@Base 2.4.0
403 Fapi_GetInfo_Async@Base 2.4.0
404 Fapi_GetInfo_Finish@Base 2.4.0
405 Fapi_GetPlatformCertificates@Base 2.4.0
406 Fapi_GetPlatformCertificates_Async@Base 2.4.0
407 Fapi_GetPlatformCertificates_Finish@Base 2.4.0
408 Fapi_GetPollHandles@Base 2.4.0
409 Fapi_GetRandom@Base 2.4.0
410 Fapi_GetRandom_Async@Base 2.4.0
411 Fapi_GetRandom_Finish@Base 2.4.0
412 Fapi_GetTcti@Base 2.4.0
413 Fapi_GetTpmBlobs@Base 2.4.0
414 Fapi_GetTpmBlobs_Async@Base 2.4.0
415 Fapi_GetTpmBlobs_Finish@Base 2.4.0
416 Fapi_Import@Base 2.4.0
417 Fapi_Import_Async@Base 2.4.0
418 Fapi_Import_Finish@Base 2.4.0
419 Fapi_Initialize@Base 2.4.0
420 Fapi_Initialize_Async@Base 2.4.0
421 Fapi_Initialize_Finish@Base 2.4.0
422 Fapi_List@Base 2.4.0
423 Fapi_List_Async@Base 2.4.0
424 Fapi_List_Finish@Base 2.4.0
425 Fapi_NvExtend@Base 2.4.0
426 Fapi_NvExtend_Async@Base 2.4.0
427 Fapi_NvExtend_Finish@Base 2.4.0
428 Fapi_NvIncrement@Base 2.4.0
429 Fapi_NvIncrement_Async@Base 2.4.0
430 Fapi_NvIncrement_Finish@Base 2.4.0
431 Fapi_NvRead@Base 2.4.0
432 Fapi_NvRead_Async@Base 2.4.0
433 Fapi_NvRead_Finish@Base 2.4.0
434 Fapi_NvSetBits@Base 2.4.0
435 Fapi_NvSetBits_Async@Base 2.4.0
436 Fapi_NvSetBits_Finish@Base 2.4.0
437 Fapi_NvWrite@Base 2.4.0
438 Fapi_NvWrite_Async@Base 2.4.0
439 Fapi_NvWrite_Finish@Base 2.4.0
440 Fapi_PcrExtend@Base 2.4.0
441 Fapi_PcrExtend_Async@Base 2.4.0
442 Fapi_PcrExtend_Finish@Base 2.4.0
443 Fapi_PcrRead@Base 2.4.0
444 Fapi_PcrRead_Async@Base 2.4.0
445 Fapi_PcrRead_Finish@Base 2.4.0
446 Fapi_Provision@Base 2.4.0
447 Fapi_Provision_Async@Base 2.4.0
448 Fapi_Provision_Finish@Base 2.4.0
449 Fapi_Quote@Base 2.4.0
450 Fapi_Quote_Async@Base 2.4.0
451 Fapi_Quote_Finish@Base 2.4.0
452 Fapi_SetAppData@Base 2.4.0
453 Fapi_SetAppData_Async@Base 2.4.0
454 Fapi_SetAppData_Finish@Base 2.4.0
455 Fapi_SetAuthCB@Base 2.4.0
456 Fapi_SetBranchCB@Base 2.4.0
457 Fapi_SetCertificate@Base 2.4.0
458 Fapi_SetCertificate_Async@Base 2.4.0
459 Fapi_SetCertificate_Finish@Base 2.4.0
460 Fapi_SetDescription@Base 2.4.0
461 Fapi_SetDescription_Async@Base 2.4.0
462 Fapi_SetDescription_Finish@Base 2.4.0
463 Fapi_SetPolicyActionCB@Base 2.4.0
464 Fapi_SetSignCB@Base 2.4.0
465 Fapi_Sign@Base 2.4.0
466 Fapi_Sign_Async@Base 2.4.0
467 Fapi_Sign_Finish@Base 2.4.0
468 Fapi_Unseal@Base 2.4.0
469 Fapi_Unseal_Async@Base 2.4.0
470 Fapi_Unseal_Finish@Base 2.4.0
471 Fapi_VerifyQuote@Base 2.4.0
472 Fapi_VerifyQuote_Async@Base 2.4.0
473 Fapi_VerifyQuote_Finish@Base 2.4.0
474 Fapi_VerifySignature@Base 2.4.0
475 Fapi_VerifySignature_Async@Base 2.4.0
476 Fapi_VerifySignature_Finish@Base 2.4.0
477 Fapi_WriteAuthorizeNv@Base 2.4.0
478 Fapi_WriteAuthorizeNv_Async@Base 2.4.0
479 Fapi_WriteAuthorizeNv_Finish@Base 2.4.0
357480 libtss2-mu.so.0 libtss2-esys0 #MINVER#
358481 Tss2_MU_BYTE_Marshal@Base 2.3.1
359482 Tss2_MU_BYTE_Unmarshal@Base 2.3.1
22 Author: Ying-Chun Liu (PaulLiu) <paulliu@debian.org>
33 Last-Update: 2019-11-10
44
5 Index: tpm2-tss-2.3.1/lib/tss2-esys.pc.in
5 Index: tpm2-tss-2.4.0/lib/tss2-esys.pc.in
66 ===================================================================
7 --- tpm2-tss-2.3.1.orig/lib/tss2-esys.pc.in
8 +++ tpm2-tss-2.3.1/lib/tss2-esys.pc.in
7 --- tpm2-tss-2.4.0.orig/lib/tss2-esys.pc.in
8 +++ tpm2-tss-2.4.0/lib/tss2-esys.pc.in
99 @@ -10,4 +10,4 @@ Version: @VERSION@
10 Requires.private: tss2-mu tss2-sys tss2-tcti-device tss2-tcti-mssim
10 Requires.private: tss2-mu tss2-sys
1111 Cflags: -I${includedir}
1212 Libs: -ltss2-esys -L${libdir}
1313 -Libs.private: @LIBDL_LDFLAGS@ @LIBSOCKET_LDFLAGS@ @TSS2_ESYS_LDFLAGS_CRYPTO@
1010 dh_autoreconf ./bootstrap
1111
1212 override_dh_auto_configure:
13 dh_auto_configure -- --enable-unit
13 dh_auto_configure -- --enable-unit --enable-doxygen-doc
1414
1515 override_dh_autoreconf_clean:
1616 rm -f compile depcomp ltmain.sh config.sub missing config.guess \
0 {
1 "profile_name": "P_RSA2048SHA256",
2 "profile_dir": "@sysconfdir@/tpm2-tss/fapi-profiles/",
3 "user_dir": "~/@userstatedir@/tpm2-tss/user/keystore",
4 "system_dir": "@localstatedir@/lib/tpm2-tss/system/keystore",
5 "tcti": "",
6 "system_pcrs" : [],
7 "log_dir" : "@runstatedir@/tpm2-tss/eventlog/"
8 }
0 {
1 "type": "TPM2_ALG_ECC",
2 "nameAlg":"TPM2_ALG_SHA256",
3 "srk_template": "system,restricted,decrypt,0x81000001",
4 "srk_persistent": 0,
5 "ek_template": "system,restricted,decrypt",
6 "ecc_signing_scheme": {
7 "scheme":"TPM2_ALG_ECDSA",
8 "details":{
9 "hashAlg":"TPM2_ALG_SHA256"
10 },
11 },
12 "sym_mode":"TPM2_ALG_CFB",
13 "sym_parameters": {
14 "algorithm":"TPM2_ALG_AES",
15 "keyBits":"128",
16 "mode":"TPM2_ALG_CFB"
17 },
18 "sym_block_size": 16,
19 "pcr_selection": [
20 { "hash": "TPM2_ALG_SHA1",
21 "pcrSelect": [ ],
22 },
23 { "hash": "TPM2_ALG_SHA256",
24 "pcrSelect": [ 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ]
25 }
26 ],
27 "curveID": "TPM2_ECC_NIST_P256",
28 "ek_policy": {
29 "description": "Endorsement hierarchy used for policy secret.",
30 "policy":[
31 {
32 "type":"POLICYSECRET",
33 "objectName": "4000000b",
34 }
35 ]
36 }
37 }
0 {
1 "type": "TPM2_ALG_RSA",
2 "nameAlg":"TPM2_ALG_SHA256",
3 "srk_template": "system,restricted,decrypt,0x81000001",
4 "srk_persistent": 1,
5 "ek_template": "system,restricted,decrypt",
6 "rsa_signing_scheme": {
7 "scheme":"TPM2_ALG_RSAPSS",
8 "details":{
9 "hashAlg":"TPM2_ALG_SHA256"
10 }
11 },
12 "rsa_decrypt_scheme": {
13 "scheme":"TPM2_ALG_OAEP",
14 "details":{
15 "hashAlg":"TPM2_ALG_SHA256"
16 }
17 },
18 "sym_mode":"TPM2_ALG_CFB",
19 "sym_parameters": {
20 "algorithm":"TPM2_ALG_AES",
21 "keyBits":"128",
22 "mode":"TPM2_ALG_CFB"
23 },
24 "sym_block_size": 16,
25 "pcr_selection": [
26 { "hash": "TPM2_ALG_SHA1",
27 "pcrSelect": [ ]
28 },
29 { "hash": "TPM2_ALG_SHA256",
30 "pcrSelect": [ 8, 9 , 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ]
31 }
32 ],
33 "exponent": 0,
34 "keyBits": 2048,
35 "session_hash_alg": "TPM2_ALG_SHA256",
36 "session_symmetric":{
37 "algorithm":"TPM2_ALG_AES",
38 "keyBits":"128",
39 "mode":"TPM2_ALG_CFB"
40 },
41 "ek_policy": {
42 "description": "Endorsement hierarchy used for policy secret.",
43 "policy":[
44 {
45 "type":"POLICYSECRET",
46 "objectName": "4000000b",
47 }
48 ]
49 }
50
51 }
0 #Type Name ID GECOS Home directory Shell
1 u tss - "tss user for tpm2"
0 #Type Path Mode User Group Age Argument
1 d @localstatedir@/lib/tpm2-tss/system/keystore 775 tss tss - -
2 d @runstatedir@/tpm2-tss/eventlog 775 tss tss - -
00 # tpm devices can only be accessed by the tss user but the tss
11 # group members can access tpmrm devices
2 KERNEL=="tpm[0-9]*", MODE="0660", OWNER="tss"
3 KERNEL=="tpmrm[0-9]*", MODE="0660", OWNER="tss", GROUP="tss"
2 KERNEL=="tpm[0-9]*", TAG+="systemd", MODE="0660", OWNER="tss"
3 KERNEL=="tpmrm[0-9]*", TAG+="systemd", MODE="0660", OWNER="tss", GROUP="tss"
2222 \fn TSS2_RC Esys_GetTcti(ESYS_CONTEXT * esys_context, TSS2_TCTI_CONTEXT ** tcti)
2323 \fn TSS2_RC Esys_GetPollHandles(ESYS_CONTEXT * esys_context, TSS2_TCTI_POLL_HANDLE ** handles, size_t * count)
2424 \fn TSS2_RC Esys_SetTimeout(ESYS_CONTEXT *esys_context, int32_t timeout)
25 \fn TSS2_RC Esys_GetSysContext(ESYS_CONTEXT *esys_context, TSS2_SYS_CONTEXT **sys_context)
26 \fn void Esys_Free(void *__ptr)
2527 \}
2628 */
2729
10101012 /*!
10111013 \defgroup iesys_crypto Internal Cryptographic Backend
10121014 \ingroup iesys
1013 The types and functions used internally be ESAPI for cryptographic operations.
1014 There may exist multiple implementations of these functions for different
1015 The types and functions used internally by ESAPI for cryptographic operations.
1016 Multiple implementations of these functions may exist for different
10151017 cryptographic backends.
10161018 \{
10171019 \def IESYS_CRYPTO_CONTEXT_BLOB
10541056
10551057 /*!
10561058 \defgroup Testgroup Testing
1059 Description of the test plan.
1060 */
1061
1062 /*!
1063 \defgroup EsysTestgroup Esys-Testing
1064 \ingroup Testgroup
10571065 \{
10581066 @brief \{
10591067 For every integration test a function with a name corresponding to the name of the source code
11461154 \}
11471155 \}
11481156 */
1157
1158 /*!
1159 \defgroup fapi Feature API
1160 Feature API (FAPI) as described in the [TSS 2.0 Feature API (FAPI) Specification](https://trustedcomputinggroup.org/wp-content/uploads/todo.pdf).
1161 This API provides a very abstract view on TPM functionalities most suitable for 80 percent of applications. In mostly uses standard types in its parameter list. Policies are encoded in JSON, whereas most key material is encoded as PEM.
1162 Both the synchronous and asynchronous API are exposed through a single library: libtss2-fapi.
1163 In order to perform an asynchronous invocation of FAPI functions, the following code serves as a template:
1164 do { r = Fapi_GetPollHandles(fc, &ph, &nph);
1165 if (r == TSS2_RC_SUCCESS) { poll(ph, nph, -1); Fapi_Free(ph); }
1166 r = Fapi_*_Finish(fc, ...); } while (r == TSS2_FAPI_RC_TRY_AGAIN);
1167 \{
1168 \typedef FAPI_CONTEXT
1169 Reference to the FAPI_CONTEXT that holds data for the connection to the TPM as
1170 well as the metadata for TPM Resource as well as links to the key- and policy
1171 store or key material for encrypted sessions.
1172 \defgroup Fapi_Initialize Fapi_Initialize
1173 FAPI functions to invoke Initialize either as one-call or in an asynchronous manner.
1174 \{
1175 \fn Fapi_Initialize(FAPI_CONTEXT **context, char const *uri)
1176 \fn Fapi_Initialize_Async(FAPI_CONTEXT **context, char const *uri)
1177 \fn Fapi_Initialize_Finish(FAPI_CONTEXT **context)
1178 \}
1179 \defgroup Fapi_Finalize Fapi_Finalize
1180 FAPI function to invoke Finalize.
1181 \{
1182 \fn Fapi_Finalize(FAPI_CONTEXT **context)
1183 \}
1184 \defgroup Fapi_GetTcti Fapi_GetTcti
1185 FAPI function to retrieve the TSS2_TCTI_CONTEXT currently used by the corresponding FAPI_CONTEXT.
1186 \{
1187 \fn Fapi_GetTcti(FAPI_CONTEXT *context, TSS2_TCTI_CONTEXT **tcti)
1188 \}
1189 \defgroup Fapi_GetPollHandles Fapi_GetPollHandles
1190 FAPI function to retrieve the poll handles currently used by the corresponding FAPI_CONTEXT.
1191 \{
1192 \fn Fapi_GetPollHandles(FAPI_CONTEXT *context, FAPI_POLL_HANDLE **handles, size_t *num_handles)
1193 \}
1194 \defgroup Fapi_Free Fapi_Free
1195 FAPI function to invoke Free.
1196 \{
1197 \fn Fapi_Free(void *ptr)
1198 \}
1199 \defgroup Fapi_GetInfo Fapi_GetInfo
1200 FAPI functions to invoke GetInfo either as one-call or in an asynchronous manner.
1201 \{
1202 \fn Fapi_GetInfo(FAPI_CONTEXT *context, char **info)
1203 \fn Fapi_GetInfo_Async(FAPI_CONTEXT *context)
1204 \fn Fapi_GetInfo_Finish(FAPI_CONTEXT *context, char **info)
1205 \}
1206 \defgroup Fapi_Provision Fapi_Provision
1207 FAPI functions to invoke Provision either as one-call or in an asynchronous manner.
1208 \{
1209 \fn Fapi_Provision(FAPI_CONTEXT *context, char const *authValueEh, char const *authValueSh, char const *authValueLockout)
1210 \fn Fapi_Provision_Async(FAPI_CONTEXT *context, char const *authValueEh, char const *authValueSh, char const *authValueLockout)
1211 \fn Fapi_Provision_Finish(FAPI_CONTEXT *context)
1212 \}
1213 \defgroup Fapi_GetPlatformCertificates Fapi_GetPlatformCertificates
1214 FAPI functions to invoke GetPlatformCertificates either as one-call or in an asynchronous manner.
1215 \{
1216 \fn Fapi_GetPlatformCertificates(FAPI_CONTEXT *context, uint8_t **certificates, size_t *certificatesSize)
1217 \fn Fapi_GetPlatformCertificates_Async(FAPI_CONTEXT *context)
1218 \fn Fapi_GetPlatformCertificates_Finish(FAPI_CONTEXT *context, uint8_t **certificates, size_t *certificatesSize)
1219 \}
1220 \defgroup Fapi_GetRandom Fapi_GetRandom
1221 FAPI functions to invoke GetRandom either as one-call or in an asynchronous manner.
1222 \{
1223 \fn Fapi_GetRandom(FAPI_CONTEXT *context, size_t numBytes, uint8_t **data)
1224 \fn Fapi_GetRandom_Async(FAPI_CONTEXT *context, size_t numBytes)
1225 \fn Fapi_GetRandom_Finish(FAPI_CONTEXT *context, uint8_t **data)
1226 \}
1227 \defgroup Fapi_Import Fapi_Import
1228 FAPI functions to invoke Import either as one-call or in an asynchronous manner.
1229 \{
1230 \fn Fapi_Import(FAPI_CONTEXT *context, char const *path, char const *importData)
1231 \fn Fapi_Import_Async(FAPI_CONTEXT *context, char const *path, char const *importData)
1232 \fn Fapi_Import_Finish(FAPI_CONTEXT *context)
1233 \}
1234 \defgroup Fapi_List Fapi_List
1235 FAPI functions to invoke List either as one-call or in an asynchronous manner.
1236 \{
1237 \fn Fapi_List(FAPI_CONTEXT *context, char const *searchPath, char **pathList)
1238 \fn Fapi_List_Async(FAPI_CONTEXT *context, char const *searchPath)
1239 \fn Fapi_List_Finish(FAPI_CONTEXT *context, char **pathlist)
1240 \}
1241 \defgroup Fapi_Delete Fapi_Delete
1242 FAPI functions to invoke Delete either as one-call or in an asynchronous manner.
1243 \{
1244 \fn Fapi_Delete(FAPI_CONTEXT *context, char const *path)
1245 \fn Fapi_Delete_Async(FAPI_CONTEXT *context, char const *path)
1246 \fn Fapi_Delete_Finish(FAPI_CONTEXT *context)
1247 \}
1248 \defgroup Fapi_ChangeAuth Fapi_ChangeAuth
1249 FAPI functions to invoke ChangeAuth either as one-call or in an asynchronous manner.
1250 \{
1251 \fn Fapi_ChangeAuth(FAPI_CONTEXT *context, char const *entityPath, char const *authValue)
1252 \fn Fapi_ChangeAuth_Async(FAPI_CONTEXT *context, char const *entityPath, char const *authValue)
1253 \fn Fapi_ChangeAuth_Finish(FAPI_CONTEXT *context)
1254 \}
1255 \defgroup Fapi_SetDescription Fapi_SetDescription
1256 FAPI functions to invoke SetDescription either as one-call or in an asynchronous manner.
1257 \{
1258 \fn Fapi_SetDescription(FAPI_CONTEXT *context, char const *path, char const *description)
1259 \fn Fapi_SetDescription_Async(FAPI_CONTEXT *context, char const *path, char const *description)
1260 \fn Fapi_SetDescription_Finish(FAPI_CONTEXT *context)
1261 \}
1262 \defgroup Fapi_GetDescription Fapi_GetDescription
1263 FAPI functions to invoke GetDescription either as one-call or in an asynchronous manner.
1264 \{
1265 \fn Fapi_GetDescription(FAPI_CONTEXT *context, char const *path, char **description)
1266 \fn Fapi_GetDescription_Async(FAPI_CONTEXT *context, char const *path)
1267 \fn Fapi_GetDescription_Finish(FAPI_CONTEXT *context, char **description)
1268 \}
1269 \defgroup Fapi_SetAppData Fapi_SetAppData
1270 FAPI functions to invoke SetAppData either as one-call or in an asynchronous manner.
1271 \{
1272 \fn Fapi_SetAppData(FAPI_CONTEXT *context, char const *path, uint8_t const *appData, size_t appDataSize)
1273 \fn Fapi_SetAppData_Async(FAPI_CONTEXT *context, char const *path, uint8_t const *appData, size_t appDataSize)
1274 \fn Fapi_SetAppData_Finish(FAPI_CONTEXT *context)
1275 \}
1276 \defgroup Fapi_GetAppData Fapi_GetAppData
1277 FAPI functions to invoke GetAppData either as one-call or in an asynchronous manner.
1278 \{
1279 \fn Fapi_GetAppData(FAPI_CONTEXT *context, char const *path, uint8_t **appData, size_t *appDataSize)
1280 \fn Fapi_GetAppData_Async(FAPI_CONTEXT *context, char const *path)
1281 \fn Fapi_GetAppData_Finish(FAPI_CONTEXT *context, uint8_t **appData, size_t *appDataSize)
1282 \}
1283 \defgroup Fapi_GetTpmBlobs Fapi_GetTpmBlobs
1284 FAPI functions to invoke GetTPMBlobs either as one-call or in an asynchronous manner.
1285 \{
1286 \fn Fapi_GetTpmBlobs(FAPI_CONTEXT *context, char const *path, uint8_t **tpm2bPublic, size_t *tpm2bPublicSize, uint8_t **tpm2bPrivate, size_t *tpm2bPrivateSize, char **policy)
1287 \fn Fapi_GetTpmBlobs_Async(FAPI_CONTEXT *context, char const *path)
1288 \fn Fapi_GetTpmBlobs_Finish(FAPI_CONTEXT *context, uint8_t **tpm2bPublic, size_t *tpm2bPublicSize, uint8_t **tpm2bPrivate, size_t *tpm2bPrivateSize, char **policy)
1289 \}
1290 \defgroup Fapi_CreateKey Fapi_CreateKey
1291 FAPI functions to invoke CreateKey either as one-call or in an asynchronous manner.
1292 \{
1293 \fn Fapi_CreateKey(FAPI_CONTEXT *context, char const *path, char const *type, char const *policyPath, char const *authvalue)
1294 \fn Fapi_CreateKey_Async(FAPI_CONTEXT *context, char const *keyPath, char const *type, char const *policyPath, char const *authvalue)
1295 \fn Fapi_CreateKey_Finish(FAPI_CONTEXT *context)
1296 \}
1297 \defgroup Fapi_Sign Fapi_Sign
1298 FAPI functions to invoke Sign either as one-call or in an asynchronous manner.
1299 \{
1300 \fn Fapi_Sign(FAPI_CONTEXT *context, char const *keyPath, char const *padding, uint8_t const *digest, size_t digestSize, uint8_t **signature, size_t *signatureSize, char **publicKey, char **certificate)
1301 \fn Fapi_Sign_Async(FAPI_CONTEXT *context, char const *keyPath, char const *padding, uint8_t const *digest, size_t digestSize)
1302 \fn Fapi_Sign_Finish(FAPI_CONTEXT *context, uint8_t **signature, size_t *signatureSize, char **publicKey, char **certificate)
1303 \}
1304 \defgroup Fapi_VerifySignature Fapi_VerifySignature
1305 FAPI functions to invoke VerifySignature either as one-call or in an asynchronous manner.
1306 \{
1307 \fn Fapi_VerifySignature(FAPI_CONTEXT *context, char const *keyPath, uint8_t const *digest, size_t digestSize, uint8_t const *signature, size_t signatureSize)
1308 \fn Fapi_VerifySignature_Async(FAPI_CONTEXT *context, char const *keyPath, uint8_t const *digest, size_t digestSize, uint8_t const *signature, size_t signatureSize)
1309 \fn Fapi_VerifySignature_Finish(FAPI_CONTEXT *context)
1310 \}
1311 \defgroup Fapi_Encrypt Fapi_Encrypt
1312 FAPI functions to invoke Encrypt either as one-call or in an asynchronous manner.
1313 \{
1314 \fn TSS2_RC Fapi_Encrypt(
1315 FAPI_CONTEXT *context,
1316 char const *keyPath,
1317 uint8_t const *plainText,
1318 size_t plainTextSize,
1319 uint8_t **cipherText,
1320 size_t *cipherTextSize)
1321
1322 \fn TSS2_RC Fapi_Encrypt_Async(
1323 FAPI_CONTEXT *context,
1324 char const *keyPath,
1325 uint8_t const *plainText,
1326 size_t plainTextSize)
1327
1328 \fn TSS2_RC Fapi_Encrypt_Finish(
1329 FAPI_CONTEXT *context,
1330 uint8_t **cipherText,
1331 size_t *cipherTextSize )
1332
1333 \}
1334 \defgroup Fapi_Decrypt Fapi_Decrypt
1335 FAPI functions to invoke Decrypt either as one-call or in an asynchronous manner.
1336 \{
1337 \fn TSS2_RC Fapi_Decrypt(
1338 FAPI_CONTEXT *context,
1339 char const *keyPath,
1340 uint8_t const *cipherText,
1341 size_t cipherTextSize,
1342 uint8_t **plainText,
1343 size_t *plainTextSize)
1344
1345 \fn TSS2_RC Fapi_Decrypt_Async(
1346 FAPI_CONTEXT *context,
1347 char const *keyPath,
1348 uint8_t const *cipherText,
1349 size_t cipherTextSize);
1350
1351 \fn TSS2_RC Fapi_Decrypt_Finish(
1352 FAPI_CONTEXT *context,
1353 uint8_t **plainText,
1354 size_t *plainTextSize)
1355 \}
1356 \defgroup Fapi_SetCertificate Fapi_SetCertificate
1357 FAPI functions to invoke SetCertificate either as one-call or in an asynchronous manner.
1358 \{
1359 \fn TSS2_RC Fapi_SetCertificate(
1360 FAPI_CONTEXT *context,
1361 char const *path,
1362 char const *x509certData)
1363
1364 \fn TSS2_RC Fapi_SetCertificate_Async(
1365 FAPI_CONTEXT *context,
1366 char const *path,
1367 char const *x509certData)
1368
1369 \fn TSS2_RC Fapi_SetCertificate_Finish(
1370 FAPI_CONTEXT *context)
1371 \}
1372 \defgroup Fapi_GetCertificate Fapi_GetCertificate
1373 FAPI functions to invoke GetCertificate either as one-call or in an asynchronous manner.
1374 \{
1375 \fn TSS2_RC Fapi_GetCertificate(
1376 FAPI_CONTEXT *context,
1377 char const *path,
1378 char **x509certData)
1379
1380 \fn TSS2_RC Fapi_GetCertificate_Async(
1381 FAPI_CONTEXT *context,
1382 char const *path)
1383
1384 \fn TSS2_RC Fapi_GetCertificate_Finish(
1385 FAPI_CONTEXT *context,
1386 char **x509certData)
1387 \}
1388 \defgroup Fapi_ExportKey Fapi_ExportKey
1389 FAPI functions to invoke ExportKey either as one-call or in an asynchronous manner.
1390 \{
1391 \fn Fapi_ExportKey(FAPI_CONTEXT *context, char const *pathOfKeyToDuplicate, char const *pathToPublicKeyOfNewParent, char **exportedData)
1392 \fn Fapi_ExportKey_Async(FAPI_CONTEXT *context, char const *pathOfKeyToDuplicate, char const *pathToPublicKeyOfNewParent)
1393 \fn Fapi_ExportKey_Finish(FAPI_CONTEXT *context, char **exportedData)
1394 \}
1395 \defgroup Fapi_CreateSeal Fapi_CreateSeal
1396 FAPI functions to invoke CreateSeal either as one-call or in an asynchronous manner.
1397 \{
1398 \fn Fapi_CreateSeal(FAPI_CONTEXT *context, char const *path, char const *type, size_t size, char const *policyPath, char const *authValue, uint8_t const *data)
1399 \fn Fapi_CreateSeal_Async(FAPI_CONTEXT *context, char const *path, char const *type, size_t size, char const *policyPath, char const *authValue, uint8_t const *data)
1400 \fn Fapi_CreateSeal_Finish(FAPI_CONTEXT *context)
1401 \}
1402 \defgroup Fapi_Unseal Fapi_Unseal
1403 FAPI functions to invoke Unseal either as one-call or in an asynchronous manner.
1404 \{
1405 \fn Fapi_Unseal(FAPI_CONTEXT *context, char const *path, uint8_t **data, size_t *size)
1406 \fn Fapi_Unseal_Async(FAPI_CONTEXT *context, char const *path)
1407 \fn Fapi_Unseal_Finish(FAPI_CONTEXT *context, uint8_t **data, size_t *size)
1408 \}
1409 \defgroup Fapi_ExportPolicy Fapi_ExportPolicy
1410 FAPI functions to invoke ExportPolicy either as one-call or in an asynchronous manner.
1411 \{
1412 \fn Fapi_ExportPolicy(FAPI_CONTEXT *context, char const *path, char **jsonPolicy)
1413 \fn Fapi_ExportPolicy_Async(FAPI_CONTEXT *context, char const *path)
1414 \fn Fapi_ExportPolicy_Finish(FAPI_CONTEXT *context, char **jsonPolicy)
1415 \}
1416 \defgroup Fapi_AuthorizePolicy Fapi_AuthorizePolicy
1417 FAPI functions to invoke AuthorizePolicy either as one-call or in an asynchronous manner.
1418 \{
1419 \fn Fapi_AuthorizePolicy(FAPI_CONTEXT *context, char const *policyPath, char const *keyPath, uint8_t const *policyRef, size_t policyRefSize)
1420 \fn Fapi_AuthorizePolicy_Async(FAPI_CONTEXT *context, char const *policyPath, char const *keyPath, uint8_t const *policyRef, size_t policyRefSize)
1421 \fn Fapi_AuthorizePolicy_Finish(FAPI_CONTEXT *context)
1422 \}
1423 \defgroup Fapi_WriteAuthorizeNv Fapi_WriteAuthorizeNv
1424 FAPI functions to invoke WriteAuthorizeNv either as one-call or in an asynchronous manner.
1425 \{
1426 \fn Fapi_WriteAuthorizeNv(FAPI_CONTEXT *context, char const *nvPath, char const *policyPath)
1427 \fn Fapi_WriteAuthorizeNv_Async(FAPI_CONTEXT *context, char const *nvPath, char const *policyPath)
1428 \fn Fapi_WriteAuthorizeNv_Finish(FAPI_CONTEXT *context)
1429 \}
1430 \defgroup Fapi_PcrRead Fapi_PcrRead
1431 FAPI functions to invoke PcrRead either as one-call or in an asynchronous manner.
1432 \{
1433 \fn Fapi_PcrRead(FAPI_CONTEXT *context, uint32_t pcrIndex, uint8_t **pcrValue, size_t *pcrValueSize, char **pcrLog)
1434 \fn Fapi_PcrRead_Async(FAPI_CONTEXT *context, uint32_t pcrIndex)
1435 \fn Fapi_PcrRead_Finish(FAPI_CONTEXT *context, uint8_t **pcrValue, size_t *pcrValueSize, char **pcrLog)
1436 \}
1437 \defgroup Fapi_PcrExtend Fapi_PcrExtend
1438 FAPI functions to invoke PcrExtend either as one-call or in an asynchronous manner.
1439 \{
1440 \fn Fapi_PcrExtend(FAPI_CONTEXT *context, uint32_t pcr, uint8_t const *data, size_t dataSize, char const *logData)
1441 \fn Fapi_PcrExtend_Async(FAPI_CONTEXT *context, uint32_t pcr, uint8_t const *data, size_t dataSize, char const *logData)
1442 \fn Fapi_PcrExtend_Finish(FAPI_CONTEXT *context)
1443 \}
1444 \defgroup Fapi_Quote Fapi_Quote
1445 FAPI functions to invoke Quote either as one-call or in an asynchronous manner.
1446 \{
1447 \fn Fapi_Quote(FAPI_CONTEXT *context, uint32_t *pcrList, size_t pcrListSize, char const *keyPath, char const *quoteType, uint8_t const *qualifyingData, size_t qualifyingDataSize, char **quoteInfo, uint8_t **signature, size_t *signatureSize, char **pcrLog, char **certificate)
1448 \fn Fapi_Quote_Async(FAPI_CONTEXT *context, uint32_t *pcrList, size_t pcrListSize, char const *keyPath, char const *quoteType, uint8_t const *qualifyingData, size_t qualifyingDataSize)
1449 \fn Fapi_Quote_Finish(FAPI_CONTEXT *context, char **quoteInfo, uint8_t **signature, size_t *signatureSize, char **pcrLog, char **certificate)
1450 \}
1451 \defgroup Fapi_VerifyQuote Fapi_VerifyQuote
1452 FAPI functions to invoke VerifyQuote either as one-call or in an asynchronous manner.
1453 \{
1454 \fn TSS2_RC Fapi_VerifyQuote(
1455 FAPI_CONTEXT *context,
1456 char const *publicKeyPath,
1457 uint8_t const *qualifyingData,
1458 size_t qualifyingDataSize,
1459 char const *quoteInfo,
1460 uint8_t const *signature,
1461 size_t signatureSize,
1462 char const *pcrLog)
1463
1464 \fn TSS2_RC Fapi_VerifyQuote_Async(
1465 FAPI_CONTEXT *context,
1466 char const *publicKeyPath,
1467 uint8_t const *qualifyingData,
1468 size_t qualifyingDataSize,
1469 char const *quoteInfo,
1470 uint8_t const *signature,
1471 size_t signatureSize,
1472 char const *pcrLog)
1473
1474 \fn TSS2_RC Fapi_VerifyQuote_Finish(
1475 FAPI_CONTEXT *context)
1476 \}
1477 \defgroup Fapi_CreateNv Fapi_CreateNv
1478 FAPI functions to invoke CreateNv either as one-call or in an asynchronous manner.
1479 \{
1480 \fn Fapi_CreateNv(FAPI_CONTEXT *context, char const *path, char const *type, size_t size, char const *policyPath, char const *authValue)
1481 \fn Fapi_CreateNv_Async(FAPI_CONTEXT *context, char const *path, char const *type, size_t size, char const *policyPath, char const *authValue)
1482 \fn Fapi_CreateNv_Finish(FAPI_CONTEXT *context)
1483 \}
1484 \defgroup Fapi_NvRead Fapi_NvRead
1485 FAPI functions to invoke NvRead either as one-call or in an asynchronous manner.
1486 \{
1487 \fn TSS2_RC Fapi_NvRead(
1488 FAPI_CONTEXT *context,
1489 char const *path,
1490 uint8_t **data,
1491 size_t *size,
1492 char **logData)
1493
1494 \fn TSS2_RC Fapi_NvRead_Async(
1495 FAPI_CONTEXT *context,
1496 char const *path)
1497
1498 \fn TSS2_RC Fapi_NvRead_Finish(
1499 FAPI_CONTEXT *context,
1500 uint8_t **data,
1501 size_t *size,
1502 char **logData)
1503 \}
1504 \defgroup Fapi_NvWrite Fapi_NvWrite
1505 FAPI functions to invoke NvWrite either as one-call or in an asynchronous manner.
1506 \{
1507 \fn Fapi_NvWrite(FAPI_CONTEXT *context, char const *path, uint8_t const *data, size_t size)
1508 \fn Fapi_NvWrite_Async(FAPI_CONTEXT *context, char const *path, uint8_t const *data, size_t size)
1509 \fn Fapi_NvWrite_Finish(FAPI_CONTEXT *context)
1510 \}
1511 \defgroup Fapi_NvExtend Fapi_NvExtend
1512 FAPI functions to invoke NvExtend either as one-call or in an asynchronous manner.
1513 \{
1514 \fn TSS2_RC Fapi_NvExtend(
1515 FAPI_CONTEXT *context,
1516 char const *path,
1517 uint8_t const *data,
1518 size_t size,
1519 char const *logData);
1520
1521 \fn TSS2_RC Fapi_NvExtend_Async(
1522 FAPI_CONTEXT *context,
1523 char const *path,
1524 uint8_t const *data,
1525 size_t size,
1526 char const *logData);
1527
1528 \fn TSS2_RC Fapi_NvExtend_Finish(
1529 FAPI_CONTEXT *context);
1530 \}
1531 \defgroup Fapi_NvIncrement Fapi_NvIncrement
1532 FAPI functions to invoke NvIncrement either as one-call or in an asynchronous manner.
1533 \{
1534 \fn Fapi_NvIncrement(FAPI_CONTEXT *context, char const *path)
1535 \fn Fapi_NvIncrement_Async(FAPI_CONTEXT *context, char const *path)
1536 \fn Fapi_NvIncrement_Finish(FAPI_CONTEXT *context)
1537 \}
1538 \defgroup Fapi_NvSetBits Fapi_NvSetBits
1539 FAPI functions to invoke NvSetBits either as one-call or in an asynchronous manner.
1540 \{
1541 \fn Fapi_NvSetBits(FAPI_CONTEXT *context, char const *path, uint64_t bitmap)
1542 \fn Fapi_NvSetBits_Async(FAPI_CONTEXT *context, char const *path, uint64_t bitmap)
1543 \fn Fapi_NvSetBits_Finish(FAPI_CONTEXT *context)
1544 \}
1545 \defgroup Fapi_SetAuthCB Fapi_SetAuthCB
1546 FAPI functions to invoke SetAuthCB.
1547 \{
1548 \fn Fapi_SetAuthCB(FAPI_CONTEXT *context, Fapi_CB_Auth callback, void *userData)
1549 \typedef (*Fapi_CB_Auth)(FAPI_CONTEXT *context, char const *description, char **auth, void *userData)
1550 \}
1551 \defgroup Fapi_SetBranchCB Fapi_SetBranchCB
1552 FAPI functions to invoke SetBranchCB.
1553 \{
1554 \fn Fapi_SetBranchCB(FAPI_CONTEXT *context, Fapi_CB_Branch callback, void *userData)
1555 \typedef (*Fapi_CB_Branch)(FAPI_CONTEXT *context, char const *description, char const **branchNames, size_t numBranches, size_t *selectedBranch, void *userData)
1556 \}
1557 \defgroup Fapi_SetSignCB Fapi_SetSignCB
1558 FAPI functions to invoke SetSignCB.
1559 \{
1560 \fn Fapi_SetSignCB(FAPI_CONTEXT *context, Fapi_CB_Sign callback, void *userData)
1561 \typedef (*Fapi_CB_Sign)(FAPI_CONTEXT *context, char const *description, char const *publicKey, char const *publicKeyHint, uint32_t hashAlg, uint8_t const *dataToSign, size_t dataToSignSize, uint8_t **signature, size_t *signatureSize, void *userData)
1562 \}
1563 \}
1564 */
1565
1566 /*!
1567 \defgroup ifapi Internals of Feature API
1568 \ingroup fapi
1569 This module holds internal APIs of the FAPI implementation.
1570
1571 Async programming style:
1572
1573 The tss2-fapi implementation uses an asynchronous programming style internally.
1574 This means that whenever a piece of code performs a potentially blocking operation
1575 it will instead return TSS2_FAPI_RC_TRY_AGAIN (similarly to ESAPI). Then this function
1576 is called again once the Poll returns ok.
1577 In order to carry the state of execution information over between the different invocation
1578 of the same function, the current state is stored in a state variable and all variables
1579 are stored in some kind of context variables.
1580 On the next entry to the function the state is evaluated using a swtich() statement and
1581 execution is resumed.
1582
1583 In order to understand the functional flow of code in FAPI, one can read the functions
1584 continuously over all fallthrough; and statecase(); statements. The statecase
1585 statements are the re-entry points of each function. The return_try_again() and FAPI_SYNC()
1586 statements are the preempt statements.
1587 \{
1588 \}
1589 */
1590
1591 /*!
1592 \defgroup fapi_crypto Internal Cryptographic Backend
1593 \ingroup ifapi
1594 The types and functions used internally by FAPI for cryptographic operations.
1595 Multiple implementations of these functions for different
1596 cryptographic backends may exist.
1597 \{
1598 \fn static TSS2_RC ecdsa_verify_signature(
1599 EVP_PKEY *publicKey,
1600 const uint8_t *signature,
1601 size_t signatureSize,
1602 const uint8_t *digest,
1603 size_t digestSize)
1604 \fn TSS2_RC get_crl_from_cert(X509 *cert, X509_CRL **crl)
1605 \fn static TSS2_RC get_ecc_tpm2b_public_from_evp(
1606 EVP_PKEY *publicKey,
1607 TPM2B_PUBLIC *tpmPublic)
1608 \fn static ENGINE * get_engine()
1609 \fn static const EVP_MD * get_hash_md(TPM2_ALG_ID hashAlgorithm)
1610 \fn static const EVP_MD * get_ossl_hash_md(TPM2_ALG_ID hashAlgorithm)
1611 \fn static TSS2_RC get_rsa_tpm2b_public_from_evp(
1612 EVP_PKEY *publicKey,
1613 TPM2B_PUBLIC *tpmPublic)
1614 \fn static int get_sig_scheme(TPM2_ALG_ID signatureScheme)
1615 \fn static int ifapi_bn2binpad(const BIGNUM *bn, unsigned char *bin, int binSize)
1616 \fn TSS2_RC ifapi_cert_to_pem(
1617 const uint8_t *certBuffer,
1618 size_t certBufferSize,
1619 char **pemCert,
1620 TPM2_ALG_ID *certAlgorithmId,
1621 TPM2B_PUBLIC *tpmPublic)
1622 \fn void ifapi_crypto_hash_abort(IFAPI_CRYPTO_CONTEXT_BLOB **context)
1623 \fn TSS2_RC ifapi_crypto_hash_finish(IFAPI_CRYPTO_CONTEXT_BLOB **context,
1624 uint8_t *digest, size_t *digestSize)
1625 \fn TSS2_RC ifapi_crypto_hash_start(IFAPI_CRYPTO_CONTEXT_BLOB **context,
1626 TPM2_ALG_ID hashAlgorithm)
1627 \fn TSS2_RC ifapi_crypto_hash_update(IFAPI_CRYPTO_CONTEXT_BLOB *context,
1628 const uint8_t *buffer, size_t size)
1629 \fn TSS2_RC ifapi_der_sig_to_tpm(
1630 const TPMT_PUBLIC *tpmPublic,
1631 const unsigned char *signature,
1632 size_t signatureSize,
1633 TPMI_ALG_HASH hashAlgorithm,
1634 TPMT_SIGNATURE *tpmSignature)
1635 \fn static TSS2_RC ifapi_ecc_der_sig_to_tpm(
1636 const unsigned char *signature,
1637 size_t signatureSize,
1638 int keySize,
1639 TPMI_ALG_HASH hashAlgorithm,
1640 TPMT_SIGNATURE *tpmSignature)
1641 \fn static TSS2_RC ifapi_get_evp_from_pem(const char *pemKey, EVP_PKEY **publicKey)
1642 \fn TSS2_RC ifapi_get_hash_alg_for_size(uint16_t size, TPMI_ALG_HASH *hashAlgorithm)
1643 \fn TPM2_RC ifapi_get_profile_sig_scheme(
1644 const IFAPI_PROFILE *profile,
1645 const TPMT_PUBLIC *tpmPublic,
1646 TPMT_SIG_SCHEME *signatureScheme)
1647 \fn TSS2_RC ifapi_get_public_from_pem_cert(const char* pem_cert, TPM2B_PUBLIC *tpm_public)
1648 \fn TPM2_ALG_ID ifapi_get_signature_algorithm_from_pem(const char *pemKey)
1649 \fn TSS2_RC ifapi_get_tpm2b_public_from_pem(
1650 const char *pemKey,
1651 TPM2B_PUBLIC *tpmPublic)
1652 \fn TSS2_RC ifapi_get_tpm_key_fingerprint(
1653 const TPM2B_PUBLIC *tpmPublicKey,
1654 TPMI_ALG_HASH hashAlg,
1655 TPM2B_DIGEST *fingerprint)
1656 \fn size_t ifapi_hash_get_digest_size(TPM2_ALG_ID hashAlgorithm)
1657 \fn TSS2_RC ifapi_initialize_sign_public(TPM2_ALG_ID signatureAlgorithm,
1658 TPM2B_PUBLIC *public)
1659 \fn TSS2_RC ifapi_pub_pem_key_from_tpm(
1660 const TPM2B_PUBLIC *tpmPublicKey,
1661 char **pemKey,
1662 int *pemKeySize)
1663 \fn TSS2_RC ifapi_tpm_ecc_sig_to_der(
1664 const TPMT_SIGNATURE *tpmSignature,
1665 uint8_t **signature,
1666 size_t *signatureSize)
1667 \fn TSS2_RC ifapi_verify_ek_cert(
1668 char* root_cert_pem,
1669 char* intermed_cert_pem,
1670 char* ek_cert_pem)
1671 \fn TSS2_RC ifapi_verify_signature(
1672 const IFAPI_OBJECT *keyObject,
1673 const uint8_t *signature,
1674 size_t signatureSize,
1675 const uint8_t *digest,
1676 size_t digestSize)
1677 \fn TSS2_RC ifapi_verify_signature_quote(
1678 const IFAPI_OBJECT *keyObject,
1679 const uint8_t *signature,
1680 size_t signatureSize,
1681 const uint8_t *digest,
1682 size_t digestSize,
1683 const TPMT_SIG_SCHEME *signatureScheme)
1684 \fn static TSS2_RC ossl_ecc_pub_from_tpm(const TPM2B_PUBLIC *tpmPublicKey, EVP_PKEY *evpPublicKey)
1685 \fn static TSS2_RC ossl_rsa_pub_from_tpm(const TPM2B_PUBLIC *tpmPublicKey, EVP_PKEY *evpPublicKey)
1686 \fn static TSS2_RC rsa_verify_signature(
1687 EVP_PKEY *publicKey,
1688 const uint8_t *signature,
1689 size_t signatureSize,
1690 const uint8_t *digest,
1691 size_t digestSize)
1692 \}
1693 */
1694
1695 /*!
1696 \defgroup ifapi_policy_intantiate Policy instantiation module
1697 \ingroup ifapi
1698 Provides functions for instantiation of the policies. The defaults will be initialized according to the given values.
1699 \{
1700 \fn static TSS2_RC get_policy_elements(TPML_POLICYELEMENTS *policy, NODE_OBJECT_T **policy_element_list)
1701 \fn TSS2_RC ifapi_policyeval_instantiate_async(
1702 IFAPI_POLICY_EVAL_INST_CTX *context,
1703 TPMS_POLICY *policy,
1704 ifapi_policyeval_INST_CB *callbacks)
1705 \fn TSS2_RC ifapi_policyeval_instantiate_finish(
1706 IFAPI_POLICY_EVAL_INST_CTX *context)
1707 \}
1708 */
1709
1710 /*!
1711 \defgroup ifapi_policy Policy calculation module
1712 \ingroup ifapi
1713 Provides functions for policy calculation (without TPM).
1714 \{
1715
1716 \fn TSS2_RC ifapi_calculate_tree(
1717 FAPI_CONTEXT *context,
1718 const char *policyPath,
1719 TPMS_POLICY *policy,
1720 TPMI_ALG_HASH hash_alg,
1721 size_t *digest_idx,
1722 size_t *hash_size)
1723
1724 \fn static TSS2_RC calculate_policy_key_param(
1725 TPM2_CC command_code,
1726 TPM2B_NAME *name,
1727 TPM2B_NONCE *policyRef,
1728 size_t hash_size,
1729 TPMI_ALG_HASH current_hash_alg,
1730 TPMU_HA *digest)
1731 \fn static void copy_policy_digest(TPML_DIGEST_VALUES *dest, TPML_DIGEST_VALUES *src,
1732 size_t digest_idx, size_t hash_size, char *txt)
1733 \fn TSS2_RC ifapi_calculate_policy(
1734 TPML_POLICYELEMENTS *policy,
1735 TPML_DIGEST_VALUES *policyDigests,
1736 TPMI_ALG_HASH hash_alg,
1737 size_t hash_size,
1738 size_t digest_idx)
1739 \fn TSS2_RC ifapi_calculate_policy_auth_value(
1740 TPMS_POLICYAUTHVALUE *policy,
1741 TPML_DIGEST_VALUES *current_digest,
1742 TPMI_ALG_HASH current_hash_alg)
1743 \fn TSS2_RC ifapi_calculate_policy_authorize(
1744 TPMS_POLICYAUTHORIZE *policy,
1745 TPML_DIGEST_VALUES *current_digest,
1746 TPMI_ALG_HASH current_hash_alg)
1747 \fn TSS2_RC ifapi_calculate_policy_authorize_nv(
1748 TPMS_POLICYAUTHORIZENV *policy,
1749 TPML_DIGEST_VALUES *current_digest,
1750 TPMI_ALG_HASH current_hash_alg)
1751 \fn TSS2_RC ifapi_calculate_policy_command_code(
1752 TPMS_POLICYCOMMANDCODE *policy,
1753 TPML_DIGEST_VALUES *current_digest,
1754 TPMI_ALG_HASH current_hash_alg)
1755 \fn TSS2_RC ifapi_calculate_policy_counter_timer(
1756 TPMS_POLICYCOUNTERTIMER *policy,
1757 TPML_DIGEST_VALUES *current_digest,
1758 TPMI_ALG_HASH current_hash_alg)
1759 \fn TSS2_RC ifapi_calculate_policy_cp_hash(
1760 TPMS_POLICYCPHASH *policy,
1761 TPML_DIGEST_VALUES *current_digest,
1762 TPMI_ALG_HASH current_hash_alg)
1763 \fn TSS2_RC ifapi_calculate_policy_digest_hash(
1764 TPM2B_DIGEST *digest,
1765 TPML_DIGEST_VALUES *current_digest,
1766 TPMI_ALG_HASH current_hash_alg,
1767 TPM2_CC command_code)
1768 \fn TSS2_RC ifapi_calculate_policy_duplicate(
1769 TPMS_POLICYDUPLICATIONSELECT *policy,
1770 TPML_DIGEST_VALUES *current_digest,
1771 TPMI_ALG_HASH current_hash_alg)
1772 \fn TSS2_RC ifapi_calculate_policy_locality(
1773 TPMS_POLICYLOCALITY *policy,
1774 TPML_DIGEST_VALUES *current_digest,
1775 TPMI_ALG_HASH current_hash_alg)
1776 \fn TSS2_RC ifapi_calculate_policy_name_hash(
1777 TPMS_POLICYNAMEHASH *policy,
1778 TPML_DIGEST_VALUES *current_digest,
1779 TPMI_ALG_HASH current_hash_alg)
1780 \fn TSS2_RC ifapi_calculate_policy_nv(
1781 TPMS_POLICYNV *policy,
1782 TPML_DIGEST_VALUES *current_digest,
1783 TPMI_ALG_HASH current_hash_alg)
1784 \fn TSS2_RC ifapi_calculate_policy_nv_written(
1785 TPMS_POLICYNVWRITTEN *policy,
1786 TPML_DIGEST_VALUES *current_digest,
1787 TPMI_ALG_HASH current_hash_alg)
1788 \fn TSS2_RC ifapi_calculate_policy_or(
1789 TPMS_POLICYOR *policyOr,
1790 TPML_DIGEST_VALUES *current_digest,
1791 TPMI_ALG_HASH hash_alg,
1792 size_t hash_size,
1793 size_t digest_idx)
1794 \fn TSS2_RC ifapi_calculate_policy_password(
1795 TPMS_POLICYPASSWORD *policy,
1796 TPML_DIGEST_VALUES *current_digest,
1797 TPMI_ALG_HASH current_hash_alg)
1798 \fn TSS2_RC ifapi_calculate_policy_physical_presence(
1799 TPMS_POLICYPHYSICALPRESENCE *policy,
1800 TPML_DIGEST_VALUES *current_digest,
1801 TPMI_ALG_HASH current_hash_alg)
1802 \fn TSS2_RC ifapi_calculate_policy_secret(
1803 TPMS_POLICYSECRET *policy,
1804 TPML_DIGEST_VALUES *current_digest,
1805 TPMI_ALG_HASH current_hash_alg)
1806 \fn TSS2_RC ifapi_calculate_policy_signed(
1807 TPMS_POLICYSIGNED *policy,
1808 TPML_DIGEST_VALUES *current_digest,
1809 TPMI_ALG_HASH current_hash_alg)
1810 \fn TSS2_RC ifapi_calculate_simple_policy(
1811 TPM2_CC command_code1,
1812 TPM2_CC command_code2,
1813 TPML_DIGEST_VALUES *current_digest,
1814 TPMI_ALG_HASH current_hash_alg)
1815 \fn TSS2_RC ifapi_compute_policy_pcr(
1816 TPMS_POLICYPCR *policy,
1817 TPML_DIGEST_VALUES *current_digest,
1818 TPMI_ALG_HASH current_hash_alg)
1819 \fn static void log_policy_digest(TPML_DIGEST_VALUES *dest, size_t digest_idx, size_t hash_size,
1820 char *txt)
1821
1822 \}
1823 */
1824
1825 /*!
1826 \defgroup ifapi_policy_callbacks Policy callback functions.
1827 \ingroup ifapi
1828 Provides internal callbacks functions for policy execution.
1829 \{
1830 \fn static void cleanup_policy_list(struct POLICY_LIST * list)
1831 \fn static TSS2_RC compare_policy_digest(
1832 TPMS_POLICY *policy,
1833 void *authPolicyVoid,
1834 void *nameAlgVoid,
1835 bool *equal)
1836 \fn static TSS2_RC equal_policy_authorization(
1837 TPMS_POLICY *policy,
1838 void *publicVoid,
1839 void *nameAlgVoid,
1840 bool *equal)
1841 \fn static void get_nv_auth_object(
1842 IFAPI_OBJECT *nv_object,
1843 ESYS_TR nv_index,
1844 IFAPI_OBJECT *auth_object,
1845 ESYS_TR *auth_index)
1846 \fn static TSS2_RC get_policy_digest(TPMS_POLICY *policy,
1847 TPMI_ALG_HASH hashAlg,
1848 TPM2B_DIGEST *digest)
1849 \fn static TSS2_RC get_policy_signature(
1850 TPMS_POLICY *policy,
1851 TPMT_PUBLIC *public,
1852 TPMT_SIGNATURE *signature)
1853 \fn TSS2_RC ifapi_branch_selection(
1854 TPML_POLICYBRANCHES *branches,
1855 size_t *branch_idx,
1856 void *userdata)
1857 \fn TSS2_RC ifapi_exec_auth_nv_policy(
1858 TPM2B_NV_PUBLIC *nv_public,
1859 TPMI_ALG_HASH hash_alg,
1860 void *userdata)
1861 \fn TSS2_RC ifapi_exec_auth_policy(
1862 TPMT_PUBLIC *key_public,
1863 TPMI_ALG_HASH hash_alg,
1864 TPM2B_DIGEST *digest,
1865 TPMT_SIGNATURE *signature,
1866 void *userdata)
1867 \fn TSS2_RC ifapi_get_duplicate_name(
1868 TPM2B_NAME *name,
1869 void *userdata)
1870 \fn TSS2_RC ifapi_get_key_public(
1871 const char *path,
1872 TPMT_PUBLIC *public,
1873 void *ctx)
1874 \fn TSS2_RC ifapi_get_nv_public(
1875 const char *path,
1876 TPM2B_NV_PUBLIC *nv_public,
1877 void *ctx)
1878 \fn TSS2_RC ifapi_get_object_name(
1879 const char *path,
1880 TPM2B_NAME *name,
1881 void *ctx)
1882 \fn TSS2_RC ifapi_policy_action(
1883 const char *action,
1884 void *userdata)
1885 \fn TSS2_RC ifapi_policyeval_cbauth(
1886 TPM2B_NAME *name,
1887 ESYS_TR *object_handle,
1888 ESYS_TR *auth_handle,
1889 ESYS_TR *authSession,
1890 void *userdata)
1891 \fn TSS2_RC ifapi_read_pcr(
1892 TPMS_PCR_SELECT *pcr_select,
1893 TPML_PCR_SELECTION *pcr_selection,
1894 TPML_PCRVALUES **pcr_values,
1895 void *ctx)
1896 \fn TSS2_RC ifapi_sign_buffer(
1897 char *key_pem,
1898 char *public_key_hint,
1899 TPMI_ALG_HASH key_pem_hash_alg,
1900 uint8_t *buffer,
1901 size_t buffer_size,
1902 uint8_t **signature,
1903 size_t *signature_size,
1904 void *userdata)
1905 \fn static TSS2_RC search_policy(
1906 FAPI_CONTEXT *context,
1907 Policy_Compare_Object compare,
1908 bool all_objects,
1909 void *object1,
1910 void *object2,
1911 struct POLICY_LIST **policy_found)
1912
1913 \}
1914 */
1915
1916 /*!
1917 \defgroup ifapi_policy_execution Policy execution functions.
1918 \ingroup ifapi
1919 Provides internal functions for policy execution.
1920 \{
1921 \fn static TSS2_RC compute_or_digest_list(
1922 TPML_POLICYBRANCHES *branches,
1923 TPMI_ALG_HASH current_hash_alg,
1924 TPML_DIGEST *digest_list)
1925 \fn static TSS2_RC compute_policy_list(
1926 IFAPI_POLICY_EXEC_CTX *pol_ctx,
1927 TPML_POLICYELEMENTS *elements)
1928 \fn static TSS2_RC execute_policy_action(
1929 ESYS_CONTEXT *esys_ctx,
1930 TPMS_POLICYACTION *policy,
1931 IFAPI_POLICY_EXEC_CTX *current_policy)
1932 \fn static TSS2_RC execute_policy_auth_value(
1933 ESYS_CONTEXT *esys_ctx,
1934 TPMS_POLICYAUTHVALUE *policy,
1935 IFAPI_POLICY_EXEC_CTX *current_policy)
1936 \fn static TSS2_RC execute_policy_authorize(
1937 ESYS_CONTEXT *esys_ctx,
1938 TPMS_POLICYAUTHORIZE *policy,
1939 TPMI_ALG_HASH hash_alg,
1940 IFAPI_POLICY_EXEC_CTX *current_policy)
1941 \fn static TSS2_RC execute_policy_authorize_nv(
1942 ESYS_CONTEXT *esys_ctx,
1943 TPMS_POLICYAUTHORIZENV *policy,
1944 TPMI_ALG_HASH hash_alg,
1945 IFAPI_POLICY_EXEC_CTX *current_policy)
1946 \fn static TSS2_RC execute_policy_command_code(
1947 ESYS_CONTEXT *esys_ctx,
1948 TPMS_POLICYCOMMANDCODE *policy,
1949 IFAPI_POLICY_EXEC_CTX *current_policy)
1950 \fn static TSS2_RC execute_policy_counter_timer(
1951 ESYS_CONTEXT *esys_ctx,
1952 TPMS_POLICYCOUNTERTIMER *policy,
1953 IFAPI_POLICY_EXEC_CTX *current_policy)
1954 \fn static TSS2_RC execute_policy_cp_hash(
1955 ESYS_CONTEXT *esys_ctx,
1956 TPMS_POLICYCPHASH *policy,
1957 IFAPI_POLICY_EXEC_CTX *current_policy)
1958 \fn static TSS2_RC execute_policy_duplicate(
1959 ESYS_CONTEXT *esys_ctx,
1960 TPMS_POLICYDUPLICATIONSELECT *policy,
1961 IFAPI_POLICY_EXEC_CTX *current_policy)
1962 \fn static TSS2_RC execute_policy_element(
1963 ESYS_CONTEXT *esys_ctx,
1964 TPMT_POLICYELEMENT *policy,
1965 TPMI_ALG_HASH hash_alg,
1966 IFAPI_POLICY_EXEC_CTX *current_policy)
1967 \fn static TSS2_RC execute_policy_locality(
1968 ESYS_CONTEXT *esys_ctx,
1969 TPMS_POLICYLOCALITY *policy,
1970 IFAPI_POLICY_EXEC_CTX *current_policy)
1971 \fn static TSS2_RC execute_policy_name_hash(
1972 ESYS_CONTEXT *esys_ctx,
1973 TPMS_POLICYNAMEHASH *policy,
1974 IFAPI_POLICY_EXEC_CTX *current_policy)
1975 \fn static TSS2_RC execute_policy_nv(
1976 ESYS_CONTEXT *esys_ctx,
1977 TPMS_POLICYNV *policy,
1978 IFAPI_POLICY_EXEC_CTX *current_policy)
1979 \fn static TSS2_RC execute_policy_nv_written(
1980 ESYS_CONTEXT *esys_ctx,
1981 TPMS_POLICYNVWRITTEN *policy,
1982 IFAPI_POLICY_EXEC_CTX *current_policy)
1983 \fn static TSS2_RC execute_policy_or(
1984 ESYS_CONTEXT *esys_ctx,
1985 TPMS_POLICYOR *policy,
1986 TPMI_ALG_HASH current_hash_alg,
1987 IFAPI_POLICY_EXEC_CTX *current_policy)
1988 \fn static TSS2_RC execute_policy_password(
1989 ESYS_CONTEXT *esys_ctx,
1990 TPMS_POLICYPASSWORD *policy,
1991 IFAPI_POLICY_EXEC_CTX *current_policy)
1992 \fn static TSS2_RC execute_policy_pcr(
1993 ESYS_CONTEXT *esys_ctx,
1994 TPMS_POLICYPCR *policy,
1995 TPMI_ALG_HASH current_hash_alg,
1996 IFAPI_POLICY_EXEC_CTX *current_policy)
1997 \fn static TSS2_RC execute_policy_physical_presence(
1998 ESYS_CONTEXT *esys_ctx,
1999 TPMS_POLICYPHYSICALPRESENCE *policy,
2000 IFAPI_POLICY_EXEC_CTX *current_policy)
2001 \fn static TSS2_RC execute_policy_secret(
2002 ESYS_CONTEXT *esys_ctx,
2003 TPMS_POLICYSECRET *policy,
2004 TPMI_ALG_HASH hash_alg,
2005 IFAPI_POLICY_EXEC_CTX *current_policy)
2006 \fn static TSS2_RC execute_policy_signed(
2007 ESYS_CONTEXT *esys_ctx,
2008 TPMS_POLICYSIGNED *policy,
2009 IFAPI_POLICY_EXEC_CTX *current_policy)
2010 \fn TSS2_RC get_policy_digest_idx(TPML_DIGEST_VALUES *digest_values, TPMI_ALG_HASH hashAlg,
2011 size_t *idx)
2012 \fn TSS2_RC ifapi_extend_authorization(
2013 TPMS_POLICY *policy,
2014 TPMS_POLICYAUTHORIZATION *authorization)
2015 \fn TSS2_RC ifapi_policyeval_execute(
2016 ESYS_CONTEXT *esys_ctx,
2017 IFAPI_POLICY_EXEC_CTX *current_policy)
2018 \fn TSS2_RC ifapi_policyeval_execute_prepare(
2019 IFAPI_POLICY_EXEC_CTX *pol_ctx,
2020 TPMI_ALG_HASH hash_alg,
2021 TPMS_POLICY *policy)
2022
2023 \}
2024 */
2025
2026 /*!
2027 \defgroup ifapi_policy_util_exec Policy utilitiy module
2028 \ingroup ifapi
2029 Provides functions for the execution of policies for object authorization.
2030 \{
2031
2032 \fn static void clear_all_policies(FAPI_CONTEXT *context)
2033 \fn static TSS2_RC clear_current_policy(FAPI_CONTEXT *context)
2034 \fn static TSS2_RC create_session(
2035 FAPI_CONTEXT *context,
2036 ESYS_TR *session,
2037 TPMI_ALG_HASH hash_alg)
2038 \fn TSS2_RC ifapi_policyutil_execute(FAPI_CONTEXT *context, ESYS_TR *session)
2039 \fn TSS2_RC ifapi_policyutil_execute_prepare(
2040 FAPI_CONTEXT *context,
2041 TPMI_ALG_HASH hash_alg,
2042 TPMS_POLICY *policy)
2043 \fn static TSS2_RC new_policy(
2044 FAPI_CONTEXT *context,
2045 TPMS_POLICY *policy,
2046 IFAPI_POLICYUTIL_STACK **current_policy)
2047
2048 \}
2049 */
2050
2051 /*!
2052 \defgroup ifapi_helper Helper functions module
2053 \ingroup ifapi
2054 Provides helper functions.
2055 \{
2056 \fn bool add_string_to_list(NODE_STR_T *str_list, char *string)
2057 \fn TSS2_RC append_object_to_list(void *object, NODE_OBJECT_T **object_list)
2058 \fn static void cleanup_policy_element(TPMT_POLICYELEMENT *policy)
2059 \fn static void cleanup_policy_elements(TPML_POLICYELEMENTS *policy)
2060 \fn static void cleanup_policy_object(POLICY_OBJECT * object)
2061 \fn static TSS2_RC copy_policy(TPMS_POLICY * dest,
2062 const TPMS_POLICY * src)
2063 \fn static TPML_POLICYBRANCHES * copy_policy_branches(const TPML_POLICYBRANCHES *from_branches)
2064 \fn static TSS2_RC copy_policy_element(const TPMT_POLICYELEMENT *from_policy, TPMT_POLICYELEMENT *to_policy)
2065 \fn static TPML_POLICYELEMENTS * copy_policy_elements(const TPML_POLICYELEMENTS *from_policy)
2066 \fn static TSS2_RC copy_policy_object(POLICY_OBJECT * dest, const POLICY_OBJECT * src)
2067 \fn static TSS2_RC copy_policyauthorization(TPMS_POLICYAUTHORIZATION * dest,
2068 const TPMS_POLICYAUTHORIZATION * src)
2069 \fn static TSS2_RC create_dirs(const char *supdir, NODE_STR_T *dir_list, mode_t mode)
2070 \fn void free_string_list(NODE_STR_T *node)
2071 \fn char * get_description(IFAPI_OBJECT *object)
2072 \fn bool ifapi_TPM2B_DIGEST_cmp(TPM2B_DIGEST *in1, TPM2B_DIGEST *in2)
2073 \fn bool ifapi_TPM2B_ECC_PARAMETER_cmp(TPM2B_ECC_PARAMETER *in1,
2074 TPM2B_ECC_PARAMETER *in2)
2075 \fn bool ifapi_TPM2B_PUBLIC_KEY_RSA_cmp(TPM2B_PUBLIC_KEY_RSA *in1,
2076 TPM2B_PUBLIC_KEY_RSA *in2)
2077 \fn bool ifapi_TPMS_ECC_POINT_cmp(TPMS_ECC_POINT *in1, TPMS_ECC_POINT *in2)
2078 \fn bool ifapi_TPMT_PUBLIC_cmp(TPMT_PUBLIC *in1, TPMT_PUBLIC *in2)
2079 \fn bool ifapi_TPMU_PUBLIC_ID_cmp(TPMU_PUBLIC_ID *in1, UINT32 selector1,
2080 TPMU_PUBLIC_ID *in2, UINT32 selector2)
2081 \fn TSS2_RC ifapi_asprintf(char **str, const char *fmt, ...)
2082 \fn TSS2_RC ifapi_calculate_pcr_digest(
2083 json_object *jso_event_list,
2084 const FAPI_QUOTE_INFO *quote_info,
2085 TPM2B_DIGEST *pcr_digest)
2086 \fn TSS2_RC ifapi_check_profile_pcr_selection(
2087 const TPML_PCR_SELECTION *pcr_profile,
2088 const TPML_PCR_SELECTION *pcr_capablity)
2089 \fn void ifapi_cleanup_policy(TPMS_POLICY *policy)
2090 \fn bool ifapi_cmp_public_key(
2091 TPM2B_PUBLIC *key1,
2092 TPM2B_PUBLIC *key2)
2093 \fn TSS2_RC ifapi_compute_policy_digest(
2094 TPML_PCRVALUES *pcrs,
2095 TPML_PCR_SELECTION *pcr_selection,
2096 TPMI_ALG_HASH hash_alg,
2097 TPM2B_DIGEST *pcr_digest)
2098 \fn TSS2_RC ifapi_compute_quote_info(
2099 IFAPI_OBJECT *sig_key_object,
2100 TPM2B_ATTEST *tpm_quoted,
2101 char **quoteInfo)
2102 \fn TPMS_POLICY * ifapi_copy_policy(
2103 const TPMS_POLICY *from_policy)
2104 \fn TSS2_RC ifapi_create_dirs(const char *supdir, const char *path)
2105 \fn TSS2_RC ifapi_extend_vpcr(
2106 TPM2B_DIGEST *vpcr,
2107 TPMI_ALG_HASH bank,
2108 const IFAPI_EVENT *event)
2109 \fn TSS2_RC ifapi_filter_pcr_selection_by_index(
2110 TPML_PCR_SELECTION *pcr_selection,
2111 const TPM2_HANDLE *pcr_index,
2112 size_t pcr_count)
2113 \fn void ifapi_free_node_list(NODE_OBJECT_T *node)
2114 \fn void ifapi_free_object_list(NODE_OBJECT_T *node)
2115 \fn int ifapi_get_curl_buffer(unsigned char * url, unsigned char ** buffer,
2116 size_t *buffer_size)
2117 \fn ESYS_TR ifapi_get_hierary_handle(const char *path)
2118 \fn TSS2_RC ifapi_get_name(TPMT_PUBLIC *publicInfo, TPM2B_NAME *name)
2119 \fn TSS2_RC ifapi_get_nv_start_index(const char *path, TPM2_HANDLE *start_nv_index)
2120 \fn TSS2_RC ifapi_get_quote_info(
2121 char const *quoteInfo,
2122 TPM2B_ATTEST *tpm_quoted,
2123 FAPI_QUOTE_INFO *fapi_quote_info)
2124 \fn bool ifapi_hierarchy_path_p(const char *path)
2125 \fn void ifapi_init_hierarchy_object(
2126 IFAPI_OBJECT *hierarchy,
2127 ESYS_TR esys_handle)
2128 \fn TSS2_RC ifapi_nv_get_name(TPM2B_NV_PUBLIC *publicInfo, TPM2B_NAME *name)
2129 \fn TSS2_RC ifapi_object_cmp_name(IFAPI_OBJECT *object, void *name, bool *equal)
2130 \fn TSS2_RC ifapi_object_cmp_nv_public(IFAPI_OBJECT *object, void *nv_public, bool *equal)
2131 \fn size_t ifapi_path_length(NODE_STR_T *node)
2132 \fn TSS2_RC ifapi_path_string(char **dest, const char *supdir, NODE_STR_T *node, char *name)
2133 \fn TSS2_RC ifapi_path_string_n(char **dest, const char *supdir, NODE_STR_T *node, char *name,
2134 size_t n)
2135 \fn bool ifapi_path_type_p(const char *path, const char *type)
2136 \fn TSS2_RC ifapi_set_key_flags(const char *type, bool policy, IFAPI_KEY_TEMPLATE *template)
2137 \fn TSS2_RC ifapi_set_nv_flags(const char *type, IFAPI_NV_TEMPLATE *template,
2138 const char *policy)
2139 \fn TSS2_RC ifapi_tpm_to_fapi_signature(
2140 IFAPI_OBJECT *sig_key_object,
2141 TPMT_SIGNATURE *tpm_signature,
2142 uint8_t **signature,
2143 size_t *signatureSize)
2144 \fn NODE_STR_T * init_string_list(const char *string)
2145 \fn bool object_with_auth(IFAPI_OBJECT *object)
2146 \fn static size_t path_str_length(NODE_STR_T *node, int delim_length)
2147 \fn TSS2_RC push_object_to_list(void *object, NODE_OBJECT_T **object_list)
2148 \fn NODE_STR_T * split_string(const char *string, char *delimiter)
2149 \fn int vasprintf(char **str, const char *fmt, va_list args)
2150 \fn static size_t write_curl_buffer_cb(void *contents, size_t size, size_t nmemb, void *userp)
2151
2152 \}
2153 */
2154
2155 /*!
2156 \defgroup ifapi_utility Utility module
2157 \ingroup ifapi
2158 Provides internal utility functions.
2159 \{
2160 \fn static void full_path_to_fapi_path(IFAPI_KEYSTORE *keystore, char *path)
2161 \fn static TSS2_RC get_explicit_key_path(
2162 IFAPI_KEYSTORE *keystore,
2163 const char *ipath,
2164 NODE_STR_T **result)
2165 \fn static size_t get_name_alg(FAPI_CONTEXT *context, IFAPI_OBJECT *object)
2166 \fn TSS2_RC ifapi_authorize_object(FAPI_CONTEXT *context, IFAPI_OBJECT *object, ESYS_TR *session)
2167 \fn TPM2_RC ifapi_capability_get(FAPI_CONTEXT *context, TPM2_CAP capability,
2168 UINT32 count, TPMS_CAPABILITY_DATA **capability_data)
2169 \fn TPM2_RC ifapi_capability_init(FAPI_CONTEXT *context)
2170 \fn TSS2_RC ifapi_change_auth_hierarchy(
2171 FAPI_CONTEXT *context,
2172 ESYS_TR handle,
2173 IFAPI_OBJECT *hierarchy_object,
2174 TPM2B_AUTH *newAuthValue)
2175 \fn TSS2_RC ifapi_change_policy_hierarchy(
2176 FAPI_CONTEXT *context,
2177 ESYS_TR handle,
2178 IFAPI_OBJECT *hierarchy_object,
2179 TPMS_POLICY *policy)
2180 \fn TSS2_RC ifapi_cleanup_session(FAPI_CONTEXT *context)
2181 \fn TSS2_RC ifapi_esys_serialize_object(ESYS_CONTEXT *ectx, IFAPI_OBJECT *object)
2182 \fn TSS2_RC ifapi_flush_object(FAPI_CONTEXT *context, ESYS_TR handle)
2183 \fn void ifapi_flush_policy_session(FAPI_CONTEXT *context, ESYS_TR session, TSS2_RC r)
2184 \fn void ifapi_free_object(FAPI_CONTEXT *context, IFAPI_OBJECT **object)
2185 \fn void ifapi_free_objects(FAPI_CONTEXT *context)
2186 \fn TSS2_RC ifapi_get_certificates(
2187 FAPI_CONTEXT *context,
2188 UINT32 min_handle,
2189 UINT32 max_handle,
2190 NODE_OBJECT_T **cert_list)
2191 \fn TSS2_RC ifapi_get_description(IFAPI_OBJECT *object, char **description)
2192 \fn TSS2_RC ifapi_get_free_handle_async(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle)
2193 \fn TSS2_RC ifapi_get_free_handle_finish(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle,
2194 TPM2_HANDLE max)
2195 \fn TSS2_RC ifapi_get_json(FAPI_CONTEXT *context, IFAPI_OBJECT *object, char **json_string)
2196 \fn TSS2_RC ifapi_get_random(FAPI_CONTEXT *context, size_t numBytes, uint8_t **data)
2197 \fn TSS2_RC ifapi_get_session_async(ESYS_CONTEXT *esys, ESYS_TR saltkey, const IFAPI_PROFILE *profile,
2198 TPMI_ALG_HASH hashAlg)
2199 \fn TSS2_RC ifapi_get_session_finish(ESYS_CONTEXT *esys, ESYS_TR *session,
2200 TPMA_SESSION flags)
2201 \fn TSS2_RC ifapi_get_sessions_async(FAPI_CONTEXT *context,
2202 IFAPI_SESSION_TYPE session_flags,
2203 TPMA_SESSION attribute_flags1,
2204 TPMA_SESSION attribute_flags2)
2205 \fn TSS2_RC ifapi_get_sessions_finish(
2206 FAPI_CONTEXT *context,
2207 const IFAPI_PROFILE *profile,
2208 TPMI_ALG_HASH hash_alg)
2209 \fn TSS2_RC ifapi_get_sig_scheme(
2210 FAPI_CONTEXT *context,
2211 IFAPI_OBJECT *object,
2212 char const *padding,
2213 TPM2B_DIGEST *digest,
2214 TPMT_SIG_SCHEME *sig_scheme)
2215 \fn TSS2_RC ifapi_init_primary_async(FAPI_CONTEXT *context, TSS2_KEY_TYPE ktype)
2216 \fn TSS2_RC ifapi_init_primary_finish(FAPI_CONTEXT *context, TSS2_KEY_TYPE ktype)
2217 \fn TSS2_RC ifapi_initialize_object(
2218 ESYS_CONTEXT *ectx,
2219 IFAPI_OBJECT *object)
2220 \fn TSS2_RC ifapi_key_create(
2221 FAPI_CONTEXT *context,
2222 IFAPI_KEY_TEMPLATE *template)
2223 \fn TSS2_RC ifapi_key_create_prepare(
2224 FAPI_CONTEXT *context,
2225 char const *keyPath,
2226 char const *policyPath)
2227 \fn TSS2_RC ifapi_key_create_prepare_auth(
2228 FAPI_CONTEXT *context,
2229 char const *keyPath,
2230 char const *policyPath,
2231 char const *authValue)
2232 \fn TSS2_RC ifapi_key_create_prepare_sensitive(
2233 FAPI_CONTEXT *context,
2234 char const *keyPath,
2235 char const *policyPath,
2236 size_t dataSize,
2237 char const *authValue,
2238 uint8_t const *data)
2239 \fn TSS2_RC ifapi_key_sign(
2240 FAPI_CONTEXT *context,
2241 IFAPI_OBJECT *sig_key_object,
2242 char const *padding,
2243 TPM2B_DIGEST *digest,
2244 TPMT_SIGNATURE **tpm_signature,
2245 char **publicKey,
2246 char **certificate)
2247 \fn TSS2_RC ifapi_load_key(
2248 FAPI_CONTEXT *context,
2249 char const *keyPath,
2250 IFAPI_OBJECT **key_object)
2251 \fn TSS2_RC ifapi_load_key_async(FAPI_CONTEXT *context, size_t position)
2252 \fn TSS2_RC ifapi_load_key_finish(FAPI_CONTEXT *context, bool flush_parent)
2253 \fn TSS2_RC ifapi_load_keys_async(FAPI_CONTEXT *context, char const *keyPath)
2254 \fn TSS2_RC ifapi_load_keys_finish(
2255 FAPI_CONTEXT *context,
2256 bool flush_parent,
2257 ESYS_TR *handle,
2258 IFAPI_OBJECT **key_object)
2259 \fn TSS2_RC ifapi_load_primary_async(FAPI_CONTEXT *context, char *path)
2260 \fn TSS2_RC ifapi_load_primary_finish(FAPI_CONTEXT *context, ESYS_TR *handle)
2261 \fn TSS2_RC ifapi_merge_profile_into_nv_template(
2262 FAPI_CONTEXT *context,
2263 IFAPI_NV_TEMPLATE *template)
2264 \fn TSS2_RC ifapi_merge_profile_into_template(
2265 const IFAPI_PROFILE *profile,
2266 IFAPI_KEY_TEMPLATE *template)
2267 \fn TSS2_RC ifapi_non_tpm_mode_init(FAPI_CONTEXT *context)
2268 \fn TSS2_RC ifapi_nv_read(
2269 FAPI_CONTEXT *context,
2270 uint8_t **data,
2271 size_t *size)
2272 \fn TSS2_RC ifapi_nv_write(
2273 FAPI_CONTEXT *context,
2274 char *nvPath,
2275 size_t param_offset,
2276 uint8_t const *data,
2277 size_t size)
2278 \fn void ifapi_primary_clean(FAPI_CONTEXT *context)
2279 \fn void ifapi_session_clean(FAPI_CONTEXT *context)
2280 \fn TSS2_RC ifapi_session_init(FAPI_CONTEXT *context)
2281 \fn TSS2_RC ifapi_set_auth(
2282 FAPI_CONTEXT *context,
2283 IFAPI_OBJECT *auth_object,
2284 const char *description)
2285 \fn void ifapi_set_description(IFAPI_OBJECT *object, char *description)
2286 \fn static TSS2_RC init_explicit_key_path(
2287 const char *context_profile,
2288 const char *ipath,
2289 NODE_STR_T **list_node1,
2290 NODE_STR_T **current_list_node,
2291 NODE_STR_T **result)
2292 \fn static size_t policy_digest_size(IFAPI_OBJECT *object)
2293 \fn static TSS2_RC pop_object_from_list(FAPI_CONTEXT *context, NODE_OBJECT_T **object_list)
2294 \fn static TSS2_RC push_object_with_size_to_list(void *object, size_t size, NODE_OBJECT_T **object_list)
2295
2296 \}
2297 */
2298
2299 /*!
2300 \defgroup ifapi_io Basic IO module
2301 \ingroup ifapi
2302 Provides internal basic IO functions for policy and key store module.
2303 \{
2304 \fn static TSS2_RC dirfiles_all(const char *dir_name, NODE_OBJECT_T **list, size_t *n)
2305 \fn TSS2_RC ifapi_io_check_create_dir(
2306 const char *dirname)
2307 \fn TSS2_RC ifapi_io_check_file_writeable(
2308 const char *file)
2309 \fn TSS2_RC ifapi_io_dirfiles(
2310 const char *dirname,
2311 char ***files,
2312 size_t *numfiles)
2313 \fn TSS2_RC ifapi_io_dirfiles_all(
2314 const char *searchPath,
2315 char ***pathlist,
2316 size_t *numPaths)
2317 \fn bool ifapi_io_path_exists(const char *path)
2318 \fn TSS2_RC ifapi_io_poll(IFAPI_IO * io)
2319 \fn TSS2_RC ifapi_io_poll_handles(IFAPI_IO *io, FAPI_POLL_HANDLE **handles, size_t *num_handles)
2320 \fn TSS2_RC ifapi_io_read_async(
2321 struct IFAPI_IO *io,
2322 const char *filename)
2323 \fn TSS2_RC ifapi_io_read_finish(
2324 struct IFAPI_IO *io,
2325 uint8_t **buffer,
2326 size_t *length)
2327 \fn TSS2_RC ifapi_io_remove_directories(
2328 const char *dirname)
2329 \fn TSS2_RC ifapi_io_remove_file(const char *file)
2330 \fn TSS2_RC ifapi_io_write_async(
2331 struct IFAPI_IO *io,
2332 const char *filename,
2333 const uint8_t *buffer,
2334 size_t length)
2335 \fn TSS2_RC ifapi_io_write_finish(
2336 struct IFAPI_IO *io)
2337
2338 \}
2339 */
2340
2341 /*!
2342 \defgroup ifapi_keystore Key store module
2343 \ingroup ifapi
2344 Provides internal fapi functions for reading and writing to the key store.
2345 \{
2346 \fn static TSS2_RC copy_uint8_ary(UINT8_ARY *dest, const UINT8_ARY * src)
2347 \fn static TSS2_RC expand_directory(IFAPI_KEYSTORE *keystore, const char *path, char **directory_name)
2348 \fn static TSS2_RC expand_path(IFAPI_KEYSTORE *keystore, const char *path, char **file_name)
2349 \fn static TSS2_RC expand_path_to_object(
2350 IFAPI_KEYSTORE *keystore,
2351 const char *path,
2352 const char *dir,
2353 char **file_name)
2354 \fn void full_path_to_fapi_path(IFAPI_KEYSTORE *keystore, char *path)
2355 \fn static TSS2_RC get_explicit_key_path(
2356 IFAPI_KEYSTORE *keystore,
2357 const char *ipath,
2358 NODE_STR_T **result)
2359 \fn void ifapi_cleanup_ifapi_duplicate(IFAPI_DUPLICATE * duplicate)
2360 \fn void ifapi_cleanup_ifapi_ext_pub_key(IFAPI_EXT_PUB_KEY * key)
2361 \fn void ifapi_cleanup_ifapi_hierarchy(IFAPI_HIERARCHY * hierarchy)
2362 \fn void ifapi_cleanup_ifapi_key(IFAPI_KEY * key)
2363 \fn void ifapi_cleanup_ifapi_keystore(IFAPI_KEYSTORE * keystore)
2364 \fn void ifapi_cleanup_ifapi_nv(IFAPI_NV * nv)
2365 \fn void ifapi_cleanup_ifapi_object(
2366 IFAPI_OBJECT * object)
2367 \fn TSS2_RC ifapi_copy_ifapi_key(IFAPI_KEY * dest, const IFAPI_KEY * src)
2368 \fn TSS2_RC ifapi_copy_ifapi_key_object(IFAPI_OBJECT * dest, const IFAPI_OBJECT * src)
2369 \fn TSS2_RC ifapi_keystore_check_overwrite(
2370 IFAPI_KEYSTORE *keystore,
2371 IFAPI_IO *io,
2372 const char *path)
2373 \fn TSS2_RC ifapi_keystore_check_writeable(
2374 IFAPI_KEYSTORE *keystore,
2375 IFAPI_IO *io,
2376 const char *path)
2377 \fn TSS2_RC ifapi_keystore_delete(
2378 IFAPI_KEYSTORE * keystore,
2379 char *path)
2380 \fn TSS2_RC ifapi_keystore_initialize(
2381 IFAPI_KEYSTORE *keystore,
2382 const char *config_systemdir,
2383 const char *config_userdir,
2384 const char *config_defaultprofile)
2385 \fn TSS2_RC ifapi_keystore_list_all(
2386 IFAPI_KEYSTORE *keystore,
2387 const char *searchpath,
2388 char ***results,
2389 size_t *numresults)
2390 \fn TSS2_RC ifapi_keystore_load_async(
2391 IFAPI_KEYSTORE *keystore,
2392 IFAPI_IO *io,
2393 const char *path)
2394 \fn TSS2_RC ifapi_keystore_load_finish(
2395 IFAPI_KEYSTORE *keystore,
2396 IFAPI_IO *io,
2397 IFAPI_OBJECT *object)
2398 \fn TSS2_RC ifapi_keystore_remove_directories(IFAPI_KEYSTORE *keystore, const char *dir_name)
2399 \fn TSS2_RC ifapi_keystore_search_nv_obj(
2400 IFAPI_KEYSTORE *keystore,
2401 IFAPI_IO *io,
2402 TPM2B_NV_PUBLIC *nv_public,
2403 char **found_path)
2404 \fn TSS2_RC ifapi_keystore_search_obj(
2405 IFAPI_KEYSTORE *keystore,
2406 IFAPI_IO *io,
2407 TPM2B_NAME *name,
2408 char **found_path)
2409 \fn TSS2_RC ifapi_keystore_store_async(
2410 IFAPI_KEYSTORE *keystore,
2411 IFAPI_IO *io,
2412 const char *path,
2413 const IFAPI_OBJECT *object)
2414 \fn TSS2_RC ifapi_keystore_store_finish(
2415 IFAPI_KEYSTORE *keystore,
2416 IFAPI_IO *io)
2417 \fn static TSS2_RC initialize_explicit_key_path(
2418 const char *context_profile,
2419 const char *ipath,
2420 NODE_STR_T **list_node1,
2421 NODE_STR_T **current_list_node,
2422 NODE_STR_T **result)
2423 \fn static TSS2_RC keystore_list_all_abs(
2424 IFAPI_KEYSTORE *keystore,
2425 const char *searchpath,
2426 char ***results,
2427 size_t *numresults)
2428 \fn static TSS2_RC keystore_search_obj(
2429 IFAPI_KEYSTORE *keystore,
2430 IFAPI_IO *io,
2431 void *cmp_object,
2432 ifapi_keystore_object_cmp cmp_function,
2433 char **found_path)
2434 \fn static TSS2_RC rel_path_to_abs_path(
2435 IFAPI_KEYSTORE *keystore,
2436 const char *rel_path,
2437 char **abs_path)
2438
2439 \}
2440 */
2441
2442 /*!
2443 \defgroup ifapi_policy_store Policy store module
2444 \ingroup ifapi
2445 Provides internal fapi functions for reading and writing to the policy store.
2446 \{
2447 \fn TSS2_RC ifapi_policy_delete(
2448 IFAPI_POLICY_STORE * pstore,
2449 char *path)
2450 \fn TSS2_RC ifapi_policy_store_initialize(
2451 IFAPI_POLICY_STORE *pstore,
2452 const char *config_policydir)
2453 \fn TSS2_RC ifapi_policy_store_load_async(
2454 IFAPI_POLICY_STORE *pstore,
2455 IFAPI_IO *io,
2456 const char *path)
2457 \fn TSS2_RC ifapi_policy_store_load_finish(
2458 IFAPI_POLICY_STORE *pstore,
2459 IFAPI_IO *io,
2460 TPMS_POLICY *policy)
2461 \fn TSS2_RC ifapi_policy_store_store_async(
2462 IFAPI_POLICY_STORE *pstore,
2463 IFAPI_IO *io,
2464 const char *path,
2465 const TPMS_POLICY *policy)
2466 \fn TSS2_RC ifapi_policy_store_store_finish(
2467 IFAPI_POLICY_STORE *pstore,
2468 IFAPI_IO *io)
2469 \fn static TSS2_RC policy_rel_path_to_abs_path(
2470 IFAPI_POLICY_STORE *pstore,
2471 const char *rel_path,
2472 char **abs_path)
2473
2474 \}
2475 */
2476
2477 /*!
2478 \defgroup ifapi_configuration Configuration utilities.
2479 \ingroup ifapi
2480 Provides internal fapi functions for deserialization of the configuration data and
2481 the initialization of the configuration.
2482 \{
2483
2484 \fn static TSS2_RC ifapi_json_IFAPI_CONFIG_deserialize(json_object *jso, IFAPI_CONFIG *out)
2485 \fn TSS2_RC ifapi_config_initialize_async(IFAPI_IO *io)
2486 \fn TSS2_RC ifapi_config_initialize_finish(IFAPI_IO *io, IFAPI_CONFIG *config)
2487 \fn static TSS2_RC ifapi_json_IFAPI_CONFIG_deserialize(json_object *jso, IFAPI_CONFIG *out)
2488
2489 \}
2490 */
2491
2492 /*!
2493 \defgroup ifapi_eventlog Event log utilities.
2494 \ingroup ifapi
2495 Provides internal fapi functions for the handling of event logs
2496 \{
2497 \fn void ifapi_cleanup_event(IFAPI_EVENT * event)
2498 \fn TSS2_RC ifapi_eventlog_append_async(
2499 IFAPI_EVENTLOG *eventlog,
2500 IFAPI_IO *io,
2501 const IFAPI_EVENT *event)
2502 \fn TSS2_RC ifapi_eventlog_append_finish(
2503 IFAPI_EVENTLOG *eventlog,
2504 IFAPI_IO *io)
2505 \fn TSS2_RC ifapi_eventlog_get_async(
2506 IFAPI_EVENTLOG *eventlog,
2507 IFAPI_IO *io,
2508 const TPM2_HANDLE *pcrList,
2509 size_t pcrListSize)
2510 \fn TSS2_RC ifapi_eventlog_get_finish(
2511 IFAPI_EVENTLOG *eventlog,
2512 IFAPI_IO *io,
2513 char **log)
2514 \fn TSS2_RC ifapi_eventlog_initialize(
2515 IFAPI_EVENTLOG *eventlog,
2516 const char *log_dir)
2517 \}
2518 */
2519
2520 /*!
2521 \defgroup ifapi_profile Profile module
2522 \ingroup ifapi
2523 Provides functions for the handling of profiles stored in the object store.
2524 \{
2525
2526 \fn static TSS2_RC ifapi_profile_checkpcrs(const TPML_PCR_SELECTION *pcr_profile)
2527 \fn static TSS2_RC ifapi_profile_json_deserialize(
2528 json_object *jso,
2529 IFAPI_PROFILE *out)
2530 \fn void ifapi_profiles_finalize(
2531 IFAPI_PROFILES *profiles)
2532 \fn TSS2_RC ifapi_profiles_get(
2533 const IFAPI_PROFILES *profiles,
2534 const char *name,
2535 const IFAPI_PROFILE **profile)
2536 \fn TSS2_RC ifapi_profiles_initialize_async(
2537 IFAPI_PROFILES *profiles,
2538 IFAPI_IO *io,
2539 const char *profilesdir,
2540 const char *defaultprofile)
2541 \fn TSS2_RC ifapi_profiles_initialize_finish(
2542 IFAPI_PROFILES *profiles,
2543 IFAPI_IO *io)
2544
2545 \}
2546 */
2547
2548 /*!
2549 \defgroup ifapi_serialization FAPI object serialization module
2550 \ingroup ifapi
2551 Provides functions for the serialization of FAPI objects to JSON.
2552 \{
2553 \fn TSS2_RC ifapi_json_FAPI_QUOTE_INFO_serialize(const FAPI_QUOTE_INFO *in,
2554 json_object **jso)
2555 \fn TSS2_RC ifapi_json_IFAPI_CAP_INFO_serialize(const IFAPI_CAP_INFO *in, json_object **jso)
2556 \fn TSS2_RC ifapi_json_IFAPI_DUPLICATE_serialize(const IFAPI_DUPLICATE *in,
2557 json_object **jso)
2558 \fn TSS2_RC ifapi_json_IFAPI_EVENT_TYPE_serialize(const IFAPI_EVENT_TYPE in,
2559 json_object **jso)
2560 \fn TSS2_RC ifapi_json_IFAPI_EVENT_TYPE_serialize_txt(
2561 const IFAPI_EVENT_TYPE in,
2562 json_object **str_jso)
2563 \fn TSS2_RC ifapi_json_IFAPI_EVENT_UNION_serialize(const IFAPI_EVENT_UNION *in,
2564 UINT32 selector, json_object **jso)
2565 \fn TSS2_RC ifapi_json_IFAPI_EVENT_serialize(const IFAPI_EVENT *in, json_object **jso)
2566 \fn TSS2_RC ifapi_json_IFAPI_EXT_PUB_KEY_serialize(const IFAPI_EXT_PUB_KEY *in,
2567 json_object **jso)
2568 \fn TSS2_RC ifapi_json_IFAPI_HIERARCHY_serialize(const IFAPI_HIERARCHY *in, json_object **jso)
2569 \fn TSS2_RC ifapi_json_IFAPI_IMA_EVENT_serialize(const IFAPI_IMA_EVENT *in,
2570 json_object **jso)
2571 \fn TSS2_RC ifapi_json_IFAPI_INFO_serialize(const IFAPI_INFO *in, json_object **jso)
2572 \fn TSS2_RC ifapi_json_IFAPI_KEY_serialize(const IFAPI_KEY *in, json_object **jso)
2573 \fn TSS2_RC ifapi_json_IFAPI_NV_serialize(const IFAPI_NV *in, json_object **jso)
2574 \fn TSS2_RC ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_serialize(const IFAPI_OBJECT_TYPE_CONSTANT
2575 in, json_object **jso)
2576 \fn TSS2_RC ifapi_json_IFAPI_OBJECT_serialize(const IFAPI_OBJECT *in,
2577 json_object **jso)
2578 \fn TSS2_RC ifapi_json_IFAPI_TSS_EVENT_serialize(const IFAPI_TSS_EVENT *in,
2579 json_object **jso)
2580 \fn TSS2_RC ifapi_json_UINT8_ARY_serialize(const UINT8_ARY *in, json_object **jso)
2581 \fn TSS2_RC ifapi_json_char_serialize(
2582 const char *in,
2583 json_object **jso)
2584 \fn TSS2_RC ifapi_json_INT32_serialize(const INT32 in, json_object **jso)
2585 \fn TSS2_RC ifapi_json_TPM2B_CREATION_DATA_serialize(const TPM2B_CREATION_DATA *in, json_object **jso)
2586 \fn TSS2_RC ifapi_json_TPM2B_DATA_serialize(const TPM2B_DATA *in, json_object **jso)
2587 \fn TSS2_RC ifapi_json_TPM2B_DIGEST_serialize(const TPM2B_DIGEST *in, json_object **jso)
2588 \fn TSS2_RC ifapi_json_TPM2B_ECC_PARAMETER_serialize(const TPM2B_ECC_PARAMETER *in, json_object **jso)
2589 \fn TSS2_RC ifapi_json_TPM2B_ENCRYPTED_SECRET_serialize(const TPM2B_ENCRYPTED_SECRET *in, json_object **jso)
2590 \fn TSS2_RC ifapi_json_TPM2B_EVENT_serialize(const TPM2B_EVENT *in, json_object **jso)
2591 \fn TSS2_RC ifapi_json_TPM2B_MAX_NV_BUFFER_serialize(const TPM2B_MAX_NV_BUFFER *in, json_object **jso)
2592 \fn TSS2_RC ifapi_json_TPM2B_NAME_serialize(const TPM2B_NAME *in, json_object **jso)
2593 \fn TSS2_RC ifapi_json_TPM2B_NONCE_serialize(const TPM2B_NONCE *in, json_object **jso)
2594 \fn TSS2_RC ifapi_json_TPM2B_NV_PUBLIC_serialize(const TPM2B_NV_PUBLIC *in, json_object **jso)
2595 \fn TSS2_RC ifapi_json_TPM2B_OPERAND_serialize(const TPM2B_OPERAND *in, json_object **jso)
2596 \fn TSS2_RC ifapi_json_TPM2B_PRIVATE_serialize(const TPM2B_PRIVATE *in, json_object **jso)
2597 \fn TSS2_RC ifapi_json_TPM2B_PUBLIC_KEY_RSA_serialize(const TPM2B_PUBLIC_KEY_RSA *in, json_object **jso)
2598 \fn TSS2_RC ifapi_json_TPM2B_PUBLIC_serialize(const TPM2B_PUBLIC *in, json_object **jso)
2599 \fn TSS2_RC ifapi_json_TPM2_ALG_ID_serialize(const TPM2_ALG_ID in, json_object **jso)
2600 \fn TSS2_RC ifapi_json_TPM2_CAP_serialize(const TPM2_CAP in, json_object **jso)
2601 \fn TSS2_RC ifapi_json_TPM2_CC_serialize(const TPM2_CC in, json_object **jso)
2602 \fn TSS2_RC ifapi_json_TPM2_ECC_CURVE_serialize(const TPM2_ECC_CURVE in, json_object **jso)
2603 \fn TSS2_RC ifapi_json_TPM2_EO_serialize(const TPM2_EO in, json_object **jso)
2604 \fn TSS2_RC ifapi_json_TPM2_GENERATED_serialize(const TPM2_GENERATED in, json_object **jso)
2605 \fn TSS2_RC ifapi_json_TPM2_HANDLE_serialize(const TPM2_HANDLE in, json_object **jso)
2606 \fn TSS2_RC ifapi_json_TPM2_NT_serialize(const TPM2_NT in, json_object **jso)
2607 \fn TSS2_RC ifapi_json_TPM2_PT_PCR_serialize(const TPM2_PT_PCR in, json_object **jso)
2608 \fn TSS2_RC ifapi_json_TPM2_PT_serialize(const TPM2_PT in, json_object **jso)
2609 \fn TSS2_RC ifapi_json_TPM2_ST_serialize(const TPM2_ST in, json_object **jso)
2610 \fn TSS2_RC ifapi_json_TPMA_ALGORITHM_serialize(const TPMA_ALGORITHM in, json_object **jso)
2611 \fn TSS2_RC ifapi_json_TPMA_CC_serialize(const TPMA_CC in, json_object **jso)
2612 \fn TSS2_RC ifapi_json_TPMA_LOCALITY_serialize(const TPMA_LOCALITY in, json_object **jso)
2613 \fn TSS2_RC ifapi_json_TPMA_NV_serialize(const TPMA_NV in, json_object **jso)
2614 \fn TSS2_RC ifapi_json_TPMA_OBJECT_serialize(const TPMA_OBJECT in, json_object **jso)
2615 \fn TSS2_RC ifapi_json_TPMI_AES_KEY_BITS_serialize(const TPMI_AES_KEY_BITS in, json_object **jso)
2616 \fn TSS2_RC ifapi_json_TPMI_ALG_ASYM_SCHEME_serialize(const TPMI_ALG_ASYM_SCHEME in, json_object **jso)
2617 \fn TSS2_RC ifapi_json_TPMI_ALG_ECC_SCHEME_serialize(const TPMI_ALG_ECC_SCHEME in, json_object **jso)
2618 \fn TSS2_RC ifapi_json_TPMI_ALG_HASH_serialize(const TPMI_ALG_HASH in, json_object **jso)
2619 \fn TSS2_RC ifapi_json_TPMI_ALG_KDF_serialize(const TPMI_ALG_KDF in, json_object **jso)
2620 \fn TSS2_RC ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_serialize(const TPMI_ALG_KEYEDHASH_SCHEME in, json_object **jso)
2621 \fn TSS2_RC ifapi_json_TPMI_ALG_PUBLIC_serialize(const TPMI_ALG_PUBLIC in, json_object **jso)
2622 \fn TSS2_RC ifapi_json_TPMI_ALG_RSA_SCHEME_serialize(const TPMI_ALG_RSA_SCHEME in, json_object **jso)
2623 \fn TSS2_RC ifapi_json_TPMI_ALG_SIG_SCHEME_serialize(const TPMI_ALG_SIG_SCHEME in,
2624 json_object **jso)
2625 \fn TSS2_RC ifapi_json_TPMI_ALG_SYM_MODE_serialize(const TPMI_ALG_SYM_MODE in,
2626 json_object **jso)
2627 \fn TSS2_RC ifapi_json_TPMI_ALG_SYM_OBJECT_serialize(const TPMI_ALG_SYM_OBJECT in,
2628 json_object **jso)
2629 \fn TSS2_RC ifapi_json_TPMI_ECC_CURVE_serialize(const TPMI_ECC_CURVE in, json_object **jso)
2630 \fn TSS2_RC ifapi_json_TPMI_RH_HIERARCHY_serialize(const TPMI_RH_HIERARCHY in,
2631 json_object **jso)
2632 \fn TSS2_RC ifapi_json_TPMI_RH_NV_INDEX_serialize(const TPMI_RH_NV_INDEX in,
2633 json_object **jso)
2634 \fn TSS2_RC ifapi_json_TPMI_RSA_KEY_BITS_serialize(const TPMI_RSA_KEY_BITS in, json_object **jso)
2635 \fn TSS2_RC ifapi_json_TPMI_ST_ATTEST_serialize(const TPMI_ST_ATTEST in, json_object **jso)
2636 \fn TSS2_RC ifapi_json_TPMI_YES_NO_serialize(const TPMI_YES_NO in, json_object **jso)
2637 \fn TSS2_RC ifapi_json_TPML_ALG_PROPERTY_serialize(const TPML_ALG_PROPERTY *in, json_object **jso)
2638 \fn TSS2_RC ifapi_json_TPML_CCA_serialize(const TPML_CCA *in, json_object **jso)
2639 \fn TSS2_RC ifapi_json_TPML_CC_serialize(const TPML_CC *in, json_object **jso)
2640 \fn TSS2_RC ifapi_json_TPML_DIGEST_VALUES_serialize(const TPML_DIGEST_VALUES *in, json_object **jso)
2641 \fn TSS2_RC ifapi_json_TPML_ECC_CURVE_serialize(const TPML_ECC_CURVE *in, json_object **jso)
2642 \fn TSS2_RC ifapi_json_TPML_HANDLE_serialize(const TPML_HANDLE *in, json_object **jso)
2643 \fn TSS2_RC ifapi_json_TPML_PCR_SELECTION_serialize(const TPML_PCR_SELECTION *in, json_object **jso)
2644 \fn TSS2_RC ifapi_json_TPML_TAGGED_PCR_PROPERTY_serialize(const TPML_TAGGED_PCR_PROPERTY *in, json_object **jso)
2645 \fn TSS2_RC ifapi_json_TPML_TAGGED_TPM_PROPERTY_serialize(const TPML_TAGGED_TPM_PROPERTY *in, json_object **jso)
2646 \fn TSS2_RC ifapi_json_TPMS_ALG_PROPERTY_serialize(const TPMS_ALG_PROPERTY *in, json_object **jso)
2647 \fn TSS2_RC ifapi_json_TPMS_ASYM_PARMS_serialize(const TPMS_ASYM_PARMS *in, json_object **jso)
2648 \fn TSS2_RC ifapi_json_TPMS_ATTEST_serialize(const TPMS_ATTEST *in, json_object **jso)
2649 \fn TSS2_RC ifapi_json_TPMS_CAPABILITY_DATA_serialize(const TPMS_CAPABILITY_DATA *in, json_object **jso)
2650 \fn TSS2_RC ifapi_json_TPMS_CERTIFY_INFO_serialize(const TPMS_CERTIFY_INFO *in, json_object **jso)
2651 \fn TSS2_RC ifapi_json_TPMS_CLOCK_INFO_serialize(const TPMS_CLOCK_INFO *in, json_object **jso)
2652 \fn TSS2_RC ifapi_json_TPMS_COMMAND_AUDIT_INFO_serialize(const TPMS_COMMAND_AUDIT_INFO *in, json_object **jso)
2653 \fn TSS2_RC ifapi_json_TPMS_CREATION_DATA_serialize(const TPMS_CREATION_DATA *in, json_object **jso)
2654 \fn TSS2_RC ifapi_json_TPMS_CREATION_INFO_serialize(const TPMS_CREATION_INFO *in, json_object **jso)
2655 \fn TSS2_RC ifapi_json_TPMS_ECC_PARMS_serialize(const TPMS_ECC_PARMS *in, json_object **jso)
2656 \fn TSS2_RC ifapi_json_TPMS_ECC_POINT_serialize(const TPMS_ECC_POINT *in, json_object **jso)
2657 \fn TSS2_RC ifapi_json_TPMS_EMPTY_serialize(const TPMS_EMPTY *in, json_object **jso)
2658 \fn TSS2_RC ifapi_json_TPMS_ENC_SCHEME_OAEP_serialize(const TPMS_ENC_SCHEME_OAEP *in, json_object **jso)
2659 \fn TSS2_RC ifapi_json_TPMS_ENC_SCHEME_RSAES_serialize(const TPMS_ENC_SCHEME_RSAES *in, json_object **jso)
2660 \fn TSS2_RC ifapi_json_TPMS_KEYEDHASH_PARMS_serialize(const TPMS_KEYEDHASH_PARMS *in, json_object **jso)
2661 \fn TSS2_RC ifapi_json_TPMS_KEY_SCHEME_ECDH_serialize(const TPMS_KEY_SCHEME_ECDH *in, json_object **jso)
2662 \fn TSS2_RC ifapi_json_TPMS_NV_CERTIFY_INFO_serialize(const TPMS_NV_CERTIFY_INFO *in, json_object **jso)
2663 \fn TSS2_RC ifapi_json_TPMS_NV_PUBLIC_serialize(const TPMS_NV_PUBLIC *in, json_object **jso)
2664 \fn TSS2_RC ifapi_json_TPMS_PCR_SELECTION_serialize(const TPMS_PCR_SELECTION *in,
2665 json_object **jso)
2666 \fn TSS2_RC ifapi_json_TPMS_PCR_SELECT_serialize(const TPMS_PCR_SELECT *in,
2667 json_object **jso)
2668 \fn TSS2_RC ifapi_json_TPMS_QUOTE_INFO_serialize(const TPMS_QUOTE_INFO *in, json_object **jso)
2669 \fn TSS2_RC ifapi_json_TPMS_RSA_PARMS_serialize(const TPMS_RSA_PARMS *in, json_object **jso)
2670 \fn TSS2_RC ifapi_json_TPMS_SCHEME_ECDAA_serialize(const TPMS_SCHEME_ECDAA *in, json_object **jso)
2671 \fn TSS2_RC ifapi_json_TPMS_SCHEME_HASH_serialize(const TPMS_SCHEME_HASH *in, json_object **jso)
2672 \fn TSS2_RC ifapi_json_TPMS_SCHEME_HMAC_serialize(const TPMS_SCHEME_HMAC *in, json_object **jso)
2673 \fn TSS2_RC ifapi_json_TPMS_SCHEME_KDF1_SP800_108_serialize(const TPMS_SCHEME_KDF1_SP800_108 *in, json_object **jso)
2674 \fn TSS2_RC ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_serialize(const TPMS_SCHEME_KDF1_SP800_56A *in, json_object **jso)
2675 \fn TSS2_RC ifapi_json_TPMS_SCHEME_MGF1_serialize(const TPMS_SCHEME_MGF1 *in, json_object **jso)
2676 \fn TSS2_RC ifapi_json_TPMS_SCHEME_XOR_serialize(const TPMS_SCHEME_XOR *in, json_object **jso)
2677 \fn TSS2_RC ifapi_json_TPMS_SESSION_AUDIT_INFO_serialize(const TPMS_SESSION_AUDIT_INFO *in, json_object **jso)
2678 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECC_serialize(const TPMS_SIGNATURE_ECC *in, json_object **jso)
2679 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECDAA_serialize(const TPMS_SIGNATURE_ECDAA *in, json_object **jso)
2680 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECDSA_serialize(const TPMS_SIGNATURE_ECDSA *in, json_object **jso)
2681 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECSCHNORR_serialize(const TPMS_SIGNATURE_ECSCHNORR *in, json_object **jso)
2682 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_RSAPSS_serialize(const TPMS_SIGNATURE_RSAPSS *in, json_object **jso)
2683 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_RSASSA_serialize(const TPMS_SIGNATURE_RSASSA *in, json_object **jso)
2684 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_RSA_serialize(const TPMS_SIGNATURE_RSA *in, json_object **jso)
2685 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_SM2_serialize(const TPMS_SIGNATURE_SM2 *in, json_object **jso)
2686 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_ECDAA_serialize(const TPMS_SIG_SCHEME_ECDAA *in, json_object **jso)
2687 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_ECDSA_serialize(const TPMS_SIG_SCHEME_ECDSA *in, json_object **jso)
2688 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_serialize(const TPMS_SIG_SCHEME_ECSCHNORR *in, json_object **jso)
2689 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_RSAPSS_serialize(const TPMS_SIG_SCHEME_RSAPSS *in, json_object **jso)
2690 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_RSASSA_serialize(const TPMS_SIG_SCHEME_RSASSA *in, json_object **jso)
2691 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_SM2_serialize(const TPMS_SIG_SCHEME_SM2 *in, json_object **jso)
2692 \fn TSS2_RC ifapi_json_TPMS_SYMCIPHER_PARMS_serialize(const TPMS_SYMCIPHER_PARMS *in, json_object **jso)
2693 \fn TSS2_RC ifapi_json_TPMS_TAGGED_PCR_SELECT_serialize(const TPMS_TAGGED_PCR_SELECT *in,
2694 json_object **jso)
2695 \fn TSS2_RC ifapi_json_TPMS_TAGGED_PROPERTY_serialize(const TPMS_TAGGED_PROPERTY *in, json_object **jso)
2696 \fn TSS2_RC ifapi_json_TPMS_TIME_ATTEST_INFO_serialize(const TPMS_TIME_ATTEST_INFO *in, json_object **jso)
2697 \fn TSS2_RC ifapi_json_TPMS_TIME_INFO_serialize(const TPMS_TIME_INFO *in, json_object **jso)
2698 \fn TSS2_RC ifapi_json_TPMT_ASYM_SCHEME_serialize(const TPMT_ASYM_SCHEME *in, json_object **jso)
2699 \fn TSS2_RC ifapi_json_TPMT_ECC_SCHEME_serialize(const TPMT_ECC_SCHEME *in, json_object **jso)
2700 \fn TSS2_RC ifapi_json_TPMT_HA_serialize(const TPMT_HA *in, json_object **jso)
2701 \fn TSS2_RC ifapi_json_TPMT_KDF_SCHEME_serialize(const TPMT_KDF_SCHEME *in, json_object **jso)
2702 \fn TSS2_RC ifapi_json_TPMT_KEYEDHASH_SCHEME_serialize(const TPMT_KEYEDHASH_SCHEME *in, json_object **jso)
2703 \fn TSS2_RC ifapi_json_TPMT_PUBLIC_serialize(const TPMT_PUBLIC *in, json_object **jso)
2704 \fn TSS2_RC ifapi_json_TPMT_RSA_SCHEME_serialize(const TPMT_RSA_SCHEME *in, json_object **jso)
2705 \fn TSS2_RC ifapi_json_TPMT_SIGNATURE_serialize(const TPMT_SIGNATURE *in, json_object **jso)
2706 \fn TSS2_RC ifapi_json_TPMT_SIG_SCHEME_serialize(const TPMT_SIG_SCHEME *in, json_object **jso)
2707 \fn TSS2_RC ifapi_json_TPMT_SYM_DEF_OBJECT_serialize(const TPMT_SYM_DEF_OBJECT *in, json_object **jso)
2708 \fn TSS2_RC ifapi_json_TPMT_TK_CREATION_serialize(const TPMT_TK_CREATION *in, json_object **jso)
2709 \fn TSS2_RC ifapi_json_TPMU_ASYM_SCHEME_serialize(const TPMU_ASYM_SCHEME *in, UINT32 selector, json_object **jso)
2710 \fn TSS2_RC ifapi_json_TPMU_ATTEST_serialize(const TPMU_ATTEST *in, UINT32 selector, json_object **jso)
2711 \fn TSS2_RC ifapi_json_TPMU_CAPABILITIES_serialize(const TPMU_CAPABILITIES *in, UINT32 selector, json_object **jso)
2712 \fn TSS2_RC ifapi_json_TPMU_HA_serialize(const TPMU_HA *in, UINT32 selector,
2713 json_object **jso)
2714 \fn TSS2_RC ifapi_json_TPMU_KDF_SCHEME_serialize(const TPMU_KDF_SCHEME *in, UINT32 selector, json_object **jso)
2715 \fn TSS2_RC ifapi_json_TPMU_PUBLIC_ID_serialize(const TPMU_PUBLIC_ID *in, UINT32 selector, json_object **jso)
2716 \fn TSS2_RC ifapi_json_TPMU_PUBLIC_PARMS_serialize(const TPMU_PUBLIC_PARMS *in, UINT32 selector, json_object **jso)
2717 \fn TSS2_RC ifapi_json_TPMU_SCHEME_KEYEDHASH_serialize(const TPMU_SCHEME_KEYEDHASH *in, UINT32 selector, json_object **jso)
2718 \fn TSS2_RC ifapi_json_TPMU_SIGNATURE_serialize(const TPMU_SIGNATURE *in, UINT32 selector, json_object **jso)
2719 \fn TSS2_RC ifapi_json_TPMU_SIG_SCHEME_serialize(const TPMU_SIG_SCHEME *in, UINT32 selector, json_object **jso)
2720 \fn TSS2_RC ifapi_json_TPMU_SYM_KEY_BITS_serialize(const TPMU_SYM_KEY_BITS *in, UINT32 selector, json_object **jso)
2721 \fn TSS2_RC ifapi_json_TPMU_SYM_MODE_serialize(const TPMU_SYM_MODE *in, UINT32 selector, json_object **jso)
2722 \fn TSS2_RC ifapi_json_UINT16_serialize(const UINT16 in, json_object **jso)
2723 \fn TSS2_RC ifapi_json_UINT32_serialize(const UINT32 in, json_object **jso)
2724 \fn TSS2_RC ifapi_json_UINT64_serialize(UINT64 in, json_object **jso)
2725 \fn TSS2_RC ifapi_json_pcr_select_serialize(
2726 const UINT8 sizeofSelect,
2727 const BYTE pcrSelect[],
2728 json_object **jso)
2729 \fn TSS2_RC ifapi_json_TPMI_POLICYTYPE_serialize(const TPMI_POLICYTYPE in,
2730 json_object **jso)
2731 \fn TSS2_RC ifapi_json_TPMI_POLICYTYPE_serialize_txt(
2732 const TPMI_POLICYTYPE in,
2733 json_object **str_jso)
2734 \fn TSS2_RC ifapi_json_TPML_PCRVALUES_serialize(const TPML_PCRVALUES *in, json_object **jso)
2735 \fn TSS2_RC ifapi_json_TPML_POLICYAUTHORIZATIONS_serialize(const TPML_POLICYAUTHORIZATIONS
2736 *in, json_object **jso)
2737 \fn TSS2_RC ifapi_json_TPML_POLICYBRANCHES_serialize(const TPML_POLICYBRANCHES *in,
2738 json_object **jso)
2739 \fn TSS2_RC ifapi_json_TPML_POLICYELEMENTS_serialize(const TPML_POLICYELEMENTS *in,
2740 json_object **jso)
2741 \fn TSS2_RC ifapi_json_TPMS_PCRVALUE_serialize(const TPMS_PCRVALUE *in, json_object **jso)
2742 \fn TSS2_RC ifapi_json_TPMS_POLICYACTION_serialize(const TPMS_POLICYACTION *in,
2743 json_object **jso)
2744 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHORIZATION_serialize(
2745 const TPMS_POLICYAUTHORIZATION *in,
2746 json_object **jso)
2747 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHORIZENV_serialize(const TPMS_POLICYAUTHORIZENV *in,
2748 json_object **jso)
2749 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHORIZE_serialize(const TPMS_POLICYAUTHORIZE *in,
2750 json_object **jso)
2751 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHVALUE_serialize(const TPMS_POLICYAUTHVALUE *in,
2752 json_object **jso)
2753 \fn TSS2_RC ifapi_json_TPMS_POLICYBRANCH_serialize(const TPMS_POLICYBRANCH *in,
2754 json_object **jso)
2755 \fn TSS2_RC ifapi_json_TPMS_POLICYCOMMANDCODE_serialize(const TPMS_POLICYCOMMANDCODE *in,
2756 json_object **jso)
2757 \fn TSS2_RC ifapi_json_TPMS_POLICYCOUNTERTIMER_serialize(const TPMS_POLICYCOUNTERTIMER *in,
2758 json_object **jso)
2759 \fn TSS2_RC ifapi_json_TPMS_POLICYCPHASH_serialize(const TPMS_POLICYCPHASH *in,
2760 json_object **jso)
2761 \fn TSS2_RC ifapi_json_TPMS_POLICYDUPLICATIONSELECT_serialize(const
2762 TPMS_POLICYDUPLICATIONSELECT *in, json_object **jso)
2763 \fn TSS2_RC ifapi_json_TPMS_POLICYLOCALITY_serialize(const TPMS_POLICYLOCALITY *in,
2764 json_object **jso)
2765 \fn TSS2_RC ifapi_json_TPMS_POLICYNAMEHASH_serialize(const TPMS_POLICYNAMEHASH *in,
2766 json_object **jso)
2767 \fn TSS2_RC ifapi_json_TPMS_POLICYNVWRITTEN_serialize(const TPMS_POLICYNVWRITTEN *in,
2768 json_object **jso)
2769 \fn TSS2_RC ifapi_json_TPMS_POLICYNV_serialize(const TPMS_POLICYNV *in, json_object **jso)
2770 \fn TSS2_RC ifapi_json_TPMS_POLICYOR_serialize(const TPMS_POLICYOR *in, json_object **jso)
2771 \fn TSS2_RC ifapi_json_TPMS_POLICYPASSWORD_serialize(const TPMS_POLICYPASSWORD *in,
2772 json_object **jso)
2773 \fn TSS2_RC ifapi_json_TPMS_POLICYPCR_serialize(const TPMS_POLICYPCR *in, json_object **jso)
2774 \fn TSS2_RC ifapi_json_TPMS_POLICYPHYSICALPRESENCE_serialize(const
2775 TPMS_POLICYPHYSICALPRESENCE *in, json_object **jso)
2776 \fn TSS2_RC ifapi_json_TPMS_POLICYSECRET_serialize(const TPMS_POLICYSECRET *in,
2777 json_object **jso)
2778 \fn TSS2_RC ifapi_json_TPMS_POLICYSIGNED_serialize(const TPMS_POLICYSIGNED *in,
2779 json_object **jso)
2780 \fn TSS2_RC ifapi_json_TPMS_POLICYTEMPLATE_serialize(const TPMS_POLICYTEMPLATE *in,
2781 json_object **jso)
2782 \fn TSS2_RC ifapi_json_TPMS_POLICY_serialize(const TPMS_POLICY *in,
2783 json_object **jso)
2784 \fn TSS2_RC ifapi_json_TPMT_POLICYELEMENT_serialize(const TPMT_POLICYELEMENT *in,
2785 json_object **jso)
2786 \fn TSS2_RC ifapi_json_TPMU_POLICYELEMENT_serialize(const TPMU_POLICYELEMENT *in,
2787 UINT32 selector, json_object **jso)
2788 \fn static TSS2_RC ifapi_json_char_serialize(
2789 const char *in,
2790 json_object **jso)
2791
2792
2793 \}
2794 */
2795
2796
2797 /*!
2798 \defgroup ifapi_deserialization FAPI object deserialization module
2799 \ingroup ifapi
2800 Provides functions for the deserialization from JSON to FAPI objects.
2801 \{
2802 \fn static bool get_number(const char *token, int64_t *num)
2803 \fn static int get_token_start_idx(const char *token)
2804 \fn TSS2_RC ifapi_json_FAPI_QUOTE_INFO_deserialize(json_object *jso, FAPI_QUOTE_INFO *out)
2805 \fn TSS2_RC ifapi_json_IFAPI_DUPLICATE_deserialize(json_object *jso, IFAPI_DUPLICATE *out)
2806 \fn TSS2_RC ifapi_json_IFAPI_EVENT_TYPE_deserialize(json_object *jso, IFAPI_EVENT_TYPE *out)
2807 \fn TSS2_RC ifapi_json_IFAPI_EVENT_TYPE_deserialize_txt(json_object *jso,
2808 IFAPI_EVENT_TYPE *out)
2809 \fn TSS2_RC ifapi_json_IFAPI_EVENT_UNION_deserialize(
2810 UINT32 selector,
2811 json_object *jso,
2812 IFAPI_EVENT_UNION *out)
2813 \fn TSS2_RC ifapi_json_IFAPI_EVENT_deserialize(json_object *jso, IFAPI_EVENT *out)
2814 \fn TSS2_RC ifapi_json_IFAPI_EXT_PUB_KEY_deserialize(json_object *jso,
2815 IFAPI_EXT_PUB_KEY *out)
2816 \fn TSS2_RC ifapi_json_IFAPI_HIERARCHY_deserialize(json_object *jso, IFAPI_HIERARCHY *out)
2817 \fn TSS2_RC ifapi_json_IFAPI_IMA_EVENT_deserialize(json_object *jso, IFAPI_IMA_EVENT *out)
2818 \fn TSS2_RC ifapi_json_IFAPI_KEY_deserialize(json_object *jso, IFAPI_KEY *out)
2819 \fn TSS2_RC ifapi_json_IFAPI_NV_deserialize(json_object *jso, IFAPI_NV *out)
2820 \fn TSS2_RC ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_deserialize(json_object *jso,
2821 IFAPI_OBJECT_TYPE_CONSTANT *out)
2822 \fn TSS2_RC ifapi_json_IFAPI_OBJECT_deserialize(json_object *jso, IFAPI_OBJECT *out)
2823 \fn TSS2_RC ifapi_json_IFAPI_TSS_EVENT_deserialize(json_object *jso, IFAPI_TSS_EVENT *out)
2824 \fn TSS2_RC ifapi_json_char_deserialize(
2825 json_object *jso,
2826 char **out)
2827 \fn static TSS2_RC get_boolean_from_json(json_object *jso, TPMI_YES_NO *value)
2828 \fn static bool get_number(const char *token, int64_t *num)
2829 \fn static TSS2_RC get_number_from_json(json_object *jso, int64_t *num)
2830 \fn bool ifapi_get_sub_object(json_object *jso, char *name, json_object **sub_jso)
2831 \fn static TSS2_RC ifapi_hex_to_byte_ary(const char hex[], UINT32 vlen, BYTE val[])
2832 \fn TSS2_RC ifapi_json_BYTE_array_deserialize(size_t max, json_object *jso, BYTE *out)
2833 \fn TSS2_RC ifapi_json_BYTE_deserialize(json_object *jso, BYTE *out)
2834 \fn TSS2_RC ifapi_json_TPM2B_CREATION_DATA_deserialize(json_object *jso,
2835 TPM2B_CREATION_DATA *out)
2836 \fn TSS2_RC ifapi_json_TPM2B_DATA_deserialize(json_object *jso, TPM2B_DATA *out)
2837 \fn TSS2_RC ifapi_json_TPM2B_DIGEST_deserialize(json_object *jso, TPM2B_DIGEST *out)
2838 \fn TSS2_RC ifapi_json_TPM2B_ECC_PARAMETER_deserialize(json_object *jso,
2839 TPM2B_ECC_PARAMETER *out)
2840 \fn TSS2_RC ifapi_json_TPM2B_ENCRYPTED_SECRET_deserialize(json_object *jso,
2841 TPM2B_ENCRYPTED_SECRET *out)
2842 \fn TSS2_RC ifapi_json_TPM2B_EVENT_deserialize(json_object *jso, TPM2B_EVENT *out)
2843 \fn TSS2_RC ifapi_json_TPM2B_MAX_NV_BUFFER_deserialize(json_object *jso,
2844 TPM2B_MAX_NV_BUFFER *out)
2845 \fn TSS2_RC ifapi_json_TPM2B_NAME_deserialize(json_object *jso, TPM2B_NAME *out)
2846 \fn TSS2_RC ifapi_json_TPM2B_NONCE_deserialize(json_object *jso, TPM2B_NONCE *out)
2847 \fn TSS2_RC ifapi_json_TPM2B_NV_PUBLIC_deserialize(json_object *jso, TPM2B_NV_PUBLIC *out)
2848 \fn TSS2_RC ifapi_json_TPM2B_OPERAND_deserialize(json_object *jso, TPM2B_OPERAND *out)
2849 \fn TSS2_RC ifapi_json_TPM2B_PRIVATE_deserialize(json_object *jso, TPM2B_PRIVATE *out)
2850 \fn TSS2_RC ifapi_json_TPM2B_PUBLIC_KEY_RSA_deserialize(json_object *jso,
2851 TPM2B_PUBLIC_KEY_RSA *out)
2852 \fn TSS2_RC ifapi_json_TPM2B_PUBLIC_deserialize(json_object *jso, TPM2B_PUBLIC *out)
2853 \fn TSS2_RC ifapi_json_TPM2_ALG_ID_deserialize(json_object *jso, TPM2_ALG_ID *out)
2854 \fn TSS2_RC ifapi_json_TPM2_CC_deserialize(json_object *jso, TPM2_CC *out)
2855 \fn TSS2_RC ifapi_json_TPM2_ECC_CURVE_deserialize(json_object *jso, TPM2_ECC_CURVE *out)
2856 \fn TSS2_RC ifapi_json_TPM2_EO_deserialize(json_object *jso, TPM2_EO *out)
2857 \fn TSS2_RC ifapi_json_TPM2_GENERATED_deserialize(json_object *jso, TPM2_GENERATED *out)
2858 \fn TSS2_RC ifapi_json_TPM2_HANDLE_deserialize(json_object *jso, TPM2_HANDLE *out)
2859 \fn TSS2_RC ifapi_json_TPM2_NT_deserialize(json_object *jso, TPM2_NT *out)
2860 \fn TSS2_RC ifapi_json_TPM2_PT_PCR_deserialize(json_object *jso, TPM2_PT_PCR *out)
2861 \fn TSS2_RC ifapi_json_TPM2_ST_deserialize(json_object *jso, TPM2_ST *out)
2862 \fn TSS2_RC ifapi_json_TPMA_LOCALITY_deserialize(json_object *jso, TPMA_LOCALITY *out)
2863 \fn TSS2_RC ifapi_json_TPMA_NV_deserialize(json_object *jso, TPMA_NV *out)
2864 \fn TSS2_RC ifapi_json_TPMA_OBJECT_deserialize(json_object *jso, TPMA_OBJECT *out)
2865 \fn TSS2_RC ifapi_json_TPMI_AES_KEY_BITS_deserialize(json_object *jso, TPMI_AES_KEY_BITS *out)
2866 \fn TSS2_RC ifapi_json_TPMI_ALG_ECC_SCHEME_deserialize(json_object *jso,
2867 TPMI_ALG_ECC_SCHEME *out)
2868 \fn TSS2_RC ifapi_json_TPMI_ALG_HASH_deserialize(json_object *jso, TPMI_ALG_HASH *out)
2869 \fn TSS2_RC ifapi_json_TPMI_ALG_KDF_deserialize(json_object *jso, TPMI_ALG_KDF *out)
2870 \fn TSS2_RC ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_deserialize(json_object *jso,
2871 TPMI_ALG_KEYEDHASH_SCHEME *out)
2872 \fn TSS2_RC ifapi_json_TPMI_ALG_PUBLIC_deserialize(json_object *jso, TPMI_ALG_PUBLIC *out)
2873 \fn TSS2_RC ifapi_json_TPMI_ALG_RSA_DECRYPT_deserialize(json_object *jso,
2874 TPMI_ALG_RSA_DECRYPT *out)
2875 \fn TSS2_RC ifapi_json_TPMI_ALG_RSA_SCHEME_deserialize(json_object *jso,
2876 TPMI_ALG_RSA_SCHEME *out)
2877 \fn TSS2_RC ifapi_json_TPMI_ALG_SIG_SCHEME_deserialize(json_object *jso,
2878 TPMI_ALG_SIG_SCHEME *out)
2879 \fn TSS2_RC ifapi_json_TPMI_ALG_SYM_MODE_deserialize(json_object *jso,
2880 TPMI_ALG_SYM_MODE *out)
2881 \fn TSS2_RC ifapi_json_TPMI_ALG_SYM_OBJECT_deserialize(json_object *jso,
2882 TPMI_ALG_SYM_OBJECT *out)
2883 \fn TSS2_RC ifapi_json_TPMI_ALG_SYM_deserialize(json_object *jso, TPMI_ALG_SYM *out)
2884 \fn TSS2_RC ifapi_json_TPMI_ECC_CURVE_deserialize(json_object *jso, TPMI_ECC_CURVE *out)
2885 \fn TSS2_RC ifapi_json_TPMI_RH_HIERARCHY_deserialize(json_object *jso,
2886 TPMI_RH_HIERARCHY *out)
2887 \fn TSS2_RC ifapi_json_TPMI_RH_NV_INDEX_deserialize(json_object *jso, TPMI_RH_NV_INDEX *out)
2888 \fn TSS2_RC ifapi_json_TPMI_RSA_KEY_BITS_deserialize(json_object *jso,
2889 TPMI_RSA_KEY_BITS *out)
2890 \fn TSS2_RC ifapi_json_TPMI_ST_ATTEST_deserialize(json_object *jso, TPMI_ST_ATTEST *out)
2891 \fn TSS2_RC ifapi_json_TPMI_YES_NO_deserialize(json_object *jso, TPMI_YES_NO *out)
2892 \fn TSS2_RC ifapi_json_TPML_DIGEST_VALUES_deserialize(json_object *jso,
2893 TPML_DIGEST_VALUES *out)
2894 \fn TSS2_RC ifapi_json_TPML_PCR_SELECTION_deserialize(json_object *jso,
2895 TPML_PCR_SELECTION *out)
2896 \fn TSS2_RC ifapi_json_TPMS_ATTEST_deserialize(json_object *jso, TPMS_ATTEST *out)
2897 \fn TSS2_RC ifapi_json_TPMS_CERTIFY_INFO_deserialize(json_object *jso,
2898 TPMS_CERTIFY_INFO *out)
2899 \fn TSS2_RC ifapi_json_TPMS_CLOCK_INFO_deserialize(json_object *jso, TPMS_CLOCK_INFO *out)
2900 \fn TSS2_RC ifapi_json_TPMS_COMMAND_AUDIT_INFO_deserialize(json_object *jso,
2901 TPMS_COMMAND_AUDIT_INFO *out)
2902 \fn TSS2_RC ifapi_json_TPMS_CREATION_DATA_deserialize(json_object *jso,
2903 TPMS_CREATION_DATA *out)
2904 \fn TSS2_RC ifapi_json_TPMS_CREATION_INFO_deserialize(json_object *jso,
2905 TPMS_CREATION_INFO *out)
2906 \fn TSS2_RC ifapi_json_TPMS_ECC_PARMS_deserialize(json_object *jso, TPMS_ECC_PARMS *out)
2907 \fn TSS2_RC ifapi_json_TPMS_ECC_POINT_deserialize(json_object *jso, TPMS_ECC_POINT *out)
2908 \fn TSS2_RC ifapi_json_TPMS_EMPTY_deserialize(json_object *jso, TPMS_EMPTY *out)
2909 \fn TSS2_RC ifapi_json_TPMS_ENC_SCHEME_OAEP_deserialize(json_object *jso,
2910 TPMS_ENC_SCHEME_OAEP *out)
2911 \fn TSS2_RC ifapi_json_TPMS_ENC_SCHEME_RSAES_deserialize(json_object *jso,
2912 TPMS_ENC_SCHEME_RSAES *out)
2913 \fn TSS2_RC ifapi_json_TPMS_KEYEDHASH_PARMS_deserialize(json_object *jso,
2914 TPMS_KEYEDHASH_PARMS *out)
2915 \fn TSS2_RC ifapi_json_TPMS_KEY_SCHEME_ECDH_deserialize(json_object *jso,
2916 TPMS_KEY_SCHEME_ECDH *out)
2917 \fn TSS2_RC ifapi_json_TPMS_NV_CERTIFY_INFO_deserialize(json_object *jso,
2918 TPMS_NV_CERTIFY_INFO *out)
2919 \fn TSS2_RC ifapi_json_TPMS_NV_PUBLIC_deserialize(json_object *jso, TPMS_NV_PUBLIC *out)
2920 \fn TSS2_RC ifapi_json_TPMS_PCR_SELECTION_deserialize(json_object *jso,
2921 TPMS_PCR_SELECTION *out)
2922 \fn TSS2_RC ifapi_json_TPMS_PCR_SELECT_deserialize(json_object *jso, TPMS_PCR_SELECT *out)
2923 \fn TSS2_RC ifapi_json_TPMS_QUOTE_INFO_deserialize(json_object *jso, TPMS_QUOTE_INFO *out)
2924 \fn TSS2_RC ifapi_json_TPMS_RSA_PARMS_deserialize(json_object *jso, TPMS_RSA_PARMS *out)
2925 \fn TSS2_RC ifapi_json_TPMS_SCHEME_ECDAA_deserialize(json_object *jso,
2926 TPMS_SCHEME_ECDAA *out)
2927 \fn TSS2_RC ifapi_json_TPMS_SCHEME_HASH_deserialize(json_object *jso,
2928 TPMS_SCHEME_HASH *out)
2929 \fn TSS2_RC ifapi_json_TPMS_SCHEME_HMAC_deserialize(json_object *jso, TPMS_SCHEME_HMAC *out)
2930 \fn TSS2_RC ifapi_json_TPMS_SCHEME_KDF1_SP800_108_deserialize(json_object *jso,
2931 TPMS_SCHEME_KDF1_SP800_108 *out)
2932 \fn TSS2_RC ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_deserialize(json_object *jso,
2933 TPMS_SCHEME_KDF1_SP800_56A *out)
2934 \fn TSS2_RC ifapi_json_TPMS_SCHEME_MGF1_deserialize(json_object *jso, TPMS_SCHEME_MGF1 *out)
2935 \fn TSS2_RC ifapi_json_TPMS_SCHEME_XOR_deserialize(json_object *jso, TPMS_SCHEME_XOR *out)
2936 \fn TSS2_RC ifapi_json_TPMS_SESSION_AUDIT_INFO_deserialize(json_object *jso,
2937 TPMS_SESSION_AUDIT_INFO *out)
2938 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECC_deserialize(json_object *jso,
2939 TPMS_SIGNATURE_ECC *out)
2940 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECDAA_deserialize(json_object *jso,
2941 TPMS_SIGNATURE_ECDAA *out)
2942 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECDSA_deserialize(json_object *jso,
2943 TPMS_SIGNATURE_ECDSA *out)
2944 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_ECSCHNORR_deserialize(json_object *jso,
2945 TPMS_SIGNATURE_ECSCHNORR *out)
2946 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_RSAPSS_deserialize(json_object *jso,
2947 TPMS_SIGNATURE_RSAPSS *out)
2948 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_RSASSA_deserialize(json_object *jso,
2949 TPMS_SIGNATURE_RSASSA *out)
2950 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_RSA_deserialize(json_object *jso,
2951 TPMS_SIGNATURE_RSA *out)
2952 \fn TSS2_RC ifapi_json_TPMS_SIGNATURE_SM2_deserialize(json_object *jso,
2953 TPMS_SIGNATURE_SM2 *out)
2954 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_ECDAA_deserialize(json_object *jso,
2955 TPMS_SIG_SCHEME_ECDAA *out)
2956 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_ECDSA_deserialize(json_object *jso,
2957 TPMS_SIG_SCHEME_ECDSA *out)
2958 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_deserialize(json_object *jso,
2959 TPMS_SIG_SCHEME_ECSCHNORR *out)
2960 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_RSAPSS_deserialize(json_object *jso,
2961 TPMS_SIG_SCHEME_RSAPSS *out)
2962 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_RSASSA_deserialize(json_object *jso,
2963 TPMS_SIG_SCHEME_RSASSA *out)
2964 \fn TSS2_RC ifapi_json_TPMS_SIG_SCHEME_SM2_deserialize(json_object *jso,
2965 TPMS_SIG_SCHEME_SM2 *out)
2966 \fn TSS2_RC ifapi_json_TPMS_SYMCIPHER_PARMS_deserialize(json_object *jso,
2967 TPMS_SYMCIPHER_PARMS *out)
2968 \fn TSS2_RC ifapi_json_TPMS_TIME_ATTEST_INFO_deserialize(json_object *jso,
2969 TPMS_TIME_ATTEST_INFO *out)
2970 \fn TSS2_RC ifapi_json_TPMS_TIME_INFO_deserialize(json_object *jso, TPMS_TIME_INFO *out)
2971 \fn TSS2_RC ifapi_json_TPMT_ECC_SCHEME_deserialize(json_object *jso, TPMT_ECC_SCHEME *out)
2972 \fn TSS2_RC ifapi_json_TPMT_HA_deserialize(json_object *jso, TPMT_HA *out)
2973 \fn TSS2_RC ifapi_json_TPMT_KDF_SCHEME_deserialize(json_object *jso, TPMT_KDF_SCHEME *out)
2974 \fn TSS2_RC ifapi_json_TPMT_KEYEDHASH_SCHEME_deserialize(json_object *jso,
2975 TPMT_KEYEDHASH_SCHEME *out)
2976 \fn TSS2_RC ifapi_json_TPMT_PUBLIC_deserialize(json_object *jso, TPMT_PUBLIC *out)
2977 \fn TSS2_RC ifapi_json_TPMT_RSA_DECRYPT_deserialize(json_object *jso,
2978 TPMT_RSA_DECRYPT *out)
2979 \fn TSS2_RC ifapi_json_TPMT_RSA_SCHEME_deserialize(json_object *jso, TPMT_RSA_SCHEME *out)
2980 \fn TSS2_RC ifapi_json_TPMT_SIGNATURE_deserialize(json_object *jso, TPMT_SIGNATURE *out)
2981 \fn TSS2_RC ifapi_json_TPMT_SIG_SCHEME_deserialize(json_object *jso, TPMT_SIG_SCHEME *out)
2982 \fn TSS2_RC ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(json_object *jso,
2983 TPMT_SYM_DEF_OBJECT *out)
2984 \fn TSS2_RC ifapi_json_TPMT_SYM_DEF_deserialize(json_object *jso, TPMT_SYM_DEF *out)
2985 \fn TSS2_RC ifapi_json_TPMT_TK_CREATION_deserialize(json_object *jso,
2986 TPMT_TK_CREATION *out)
2987 \fn TSS2_RC ifapi_json_TPMT_TK_VERIFIED_deserialize(json_object *jso,
2988 TPMT_TK_VERIFIED *out)
2989 \fn TSS2_RC ifapi_json_TPMU_ASYM_SCHEME_deserialize(
2990 UINT32 selector,
2991 json_object *jso,
2992 TPMU_ASYM_SCHEME *out)
2993 \fn TSS2_RC ifapi_json_TPMU_ATTEST_deserialize(
2994 UINT32 selector,
2995 json_object *jso,
2996 TPMU_ATTEST *out)
2997 \fn TSS2_RC ifapi_json_TPMU_HA_deserialize(
2998 UINT32 selector,
2999 json_object *jso,
3000 TPMU_HA *out)
3001 \fn TSS2_RC ifapi_json_TPMU_KDF_SCHEME_deserialize(
3002 UINT32 selector,
3003 json_object *jso,
3004 TPMU_KDF_SCHEME *out)
3005 \fn TSS2_RC ifapi_json_TPMU_PUBLIC_ID_deserialize(
3006 UINT32 selector,
3007 json_object *jso,
3008 TPMU_PUBLIC_ID *out)
3009 \fn TSS2_RC ifapi_json_TPMU_PUBLIC_PARMS_deserialize(
3010 UINT32 selector,
3011 json_object *jso,
3012 TPMU_PUBLIC_PARMS *out)
3013 \fn TSS2_RC ifapi_json_TPMU_SCHEME_KEYEDHASH_deserialize(
3014 UINT32 selector,
3015 json_object *jso,
3016 TPMU_SCHEME_KEYEDHASH *out)
3017 \fn TSS2_RC ifapi_json_TPMU_SIGNATURE_deserialize(
3018 UINT32 selector,
3019 json_object *jso,
3020 TPMU_SIGNATURE *out)
3021 \fn TSS2_RC ifapi_json_TPMU_SIG_SCHEME_deserialize(
3022 UINT32 selector,
3023 json_object *jso,
3024 TPMU_SIG_SCHEME *out)
3025 \fn TSS2_RC ifapi_json_TPMU_SYM_KEY_BITS_deserialize(
3026 UINT32 selector,
3027 json_object *jso,
3028 TPMU_SYM_KEY_BITS *out)
3029 \fn TSS2_RC ifapi_json_TPMU_SYM_MODE_deserialize(
3030 UINT32 selector,
3031 json_object *jso,
3032 TPMU_SYM_MODE *out)
3033 \fn TSS2_RC ifapi_json_UINT16_deserialize(json_object *jso, UINT16 *out)
3034 \fn TSS2_RC ifapi_json_UINT32_deserialize(json_object *jso, UINT32 *out)
3035 \fn TSS2_RC ifapi_json_UINT64_deserialize(json_object *jso, UINT64 *out)
3036 \fn TSS2_RC ifapi_json_UINT8_ARY_deserialize(
3037 json_object *jso,
3038 UINT8_ARY *out)
3039 \fn TSS2_RC ifapi_json_UINT8_deserialize(json_object *jso, UINT8 *out)
3040 \fn TSS2_RC ifapi_json_byte_deserialize(
3041 json_object *jso,
3042 UINT32 max,
3043 BYTE *out,
3044 UINT16 *out_size)
3045 \fn TSS2_RC ifapi_json_pcr_selection_deserialize(
3046 json_object *jso,
3047 UINT8 *sizeofSelect,
3048 BYTE pcrSelect[])
3049 \fn static const char * strip_prefix(const char *in, ...)
3050 \fn static bool get_number(const char *token, int64_t *num)
3051 \fn static int get_token_start_idx(const char *token)
3052 \fn TSS2_RC ifapi_json_TPMI_POLICYTYPE_deserialize(json_object *jso, TPMI_POLICYTYPE *out)
3053 \fn TSS2_RC ifapi_json_TPMI_POLICYTYPE_deserialize_txt(json_object *jso,
3054 TPMI_POLICYTYPE *out)
3055 \fn TSS2_RC ifapi_json_TPML_PCRVALUES_deserialize(json_object *jso, TPML_PCRVALUES **out)
3056 \fn TSS2_RC ifapi_json_TPML_POLICYAUTHORIZATIONS_deserialize(json_object *jso,
3057 TPML_POLICYAUTHORIZATIONS **out)
3058 \fn TSS2_RC ifapi_json_TPML_POLICYBRANCHES_deserialize(json_object *jso,
3059 TPML_POLICYBRANCHES **out)
3060 \fn TSS2_RC ifapi_json_TPML_POLICYELEMENTS_deserialize(json_object *jso,
3061 TPML_POLICYELEMENTS **out)
3062 \fn TSS2_RC ifapi_json_TPMS_PCRVALUE_deserialize(json_object *jso, TPMS_PCRVALUE *out)
3063 \fn TSS2_RC ifapi_json_TPMS_POLICYACTION_deserialize(json_object *jso,
3064 TPMS_POLICYACTION *out)
3065 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHORIZATION_deserialize(json_object *jso,
3066 TPMS_POLICYAUTHORIZATION *out)
3067 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHORIZENV_deserialize(json_object *jso,
3068 TPMS_POLICYAUTHORIZENV *out)
3069 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHORIZE_deserialize(json_object *jso,
3070 TPMS_POLICYAUTHORIZE *out)
3071 \fn TSS2_RC ifapi_json_TPMS_POLICYAUTHVALUE_deserialize(json_object *jso,
3072 TPMS_POLICYAUTHVALUE *out)
3073 \fn TSS2_RC ifapi_json_TPMS_POLICYBRANCH_deserialize(json_object *jso,
3074 TPMS_POLICYBRANCH *out)
3075 \fn TSS2_RC ifapi_json_TPMS_POLICYCOMMANDCODE_deserialize(json_object *jso,
3076 TPMS_POLICYCOMMANDCODE *out)
3077 \fn TSS2_RC ifapi_json_TPMS_POLICYCOUNTERTIMER_deserialize(json_object *jso,
3078 TPMS_POLICYCOUNTERTIMER *out)
3079 \fn TSS2_RC ifapi_json_TPMS_POLICYCPHASH_deserialize(json_object *jso,
3080 TPMS_POLICYCPHASH *out)
3081 \fn TSS2_RC ifapi_json_TPMS_POLICYDUPLICATIONSELECT_deserialize(json_object *jso,
3082 TPMS_POLICYDUPLICATIONSELECT *out)
3083 \fn TSS2_RC ifapi_json_TPMS_POLICYLOCALITY_deserialize(json_object *jso,
3084 TPMS_POLICYLOCALITY *out)
3085 \fn TSS2_RC ifapi_json_TPMS_POLICYNAMEHASH_deserialize(json_object *jso,
3086 TPMS_POLICYNAMEHASH *out)
3087 \fn TSS2_RC ifapi_json_TPMS_POLICYNVWRITTEN_deserialize(json_object *jso,
3088 TPMS_POLICYNVWRITTEN *out)
3089 \fn TSS2_RC ifapi_json_TPMS_POLICYNV_deserialize(json_object *jso, TPMS_POLICYNV *out)
3090 \fn TSS2_RC ifapi_json_TPMS_POLICYOR_deserialize(json_object *jso, TPMS_POLICYOR *out)
3091 \fn TSS2_RC ifapi_json_TPMS_POLICYPASSWORD_deserialize(json_object *jso,
3092 TPMS_POLICYPASSWORD *out)
3093 \fn TSS2_RC ifapi_json_TPMS_POLICYPCR_deserialize(json_object *jso, TPMS_POLICYPCR *out)
3094 \fn TSS2_RC ifapi_json_TPMS_POLICYPHYSICALPRESENCE_deserialize(json_object *jso,
3095 TPMS_POLICYPHYSICALPRESENCE *out)
3096 \fn TSS2_RC ifapi_json_TPMS_POLICYSECRET_deserialize(json_object *jso,
3097 TPMS_POLICYSECRET *out)
3098 \fn TSS2_RC ifapi_json_TPMS_POLICYSIGNED_deserialize(json_object *jso,
3099 TPMS_POLICYSIGNED *out)
3100 \fn TSS2_RC ifapi_json_TPMS_POLICYTEMPLATE_deserialize(json_object *jso,
3101 TPMS_POLICYTEMPLATE *out)
3102 \fn TSS2_RC ifapi_json_TPMS_POLICY_deserialize(json_object *jso,
3103 TPMS_POLICY *out)
3104 \fn TSS2_RC ifapi_json_TPMT_POLICYELEMENT_deserialize(json_object *jso,
3105 TPMT_POLICYELEMENT *out)
3106 \fn TSS2_RC ifapi_json_TPMU_POLICYELEMENT_deserialize(
3107 UINT32 selector,
3108 json_object *jso,
3109 TPMU_POLICYELEMENT *out)
3110
3111
3112 \}
3113 */
3114
3115 /*!
3116 \defgroup ifapi_vendor Vendor specific module
3117 \ingroup ifapi
3118 \{
3119 Provides functions implementing vendor specific extensions.
3120 \fn TSS2_RC ifapi_get_intl_ek_certificate(FAPI_CONTEXT *context, TPM2B_PUBLIC *ek_public,
3121 unsigned char ** cert_buffer, size_t *cert_size)
3122
3123
3124 \}
3125 */
3126
3127 /*!
3128 \defgroup FapiTestgroup Fapi-Testing
3129 Testing of FAPI functionality. The tested FAPI functions are listed in each
3130 of the testcase functions' descriptions.
3131 \ingroup Testgroup
3132 \{
3133 \fn test_fapi_data_crypt(FAPI_CONTEXT *context)
3134 \fn test_fapi_duplicate(FAPI_CONTEXT *context)
3135 \fn test_fapi_ext_public_key(FAPI_CONTEXT *context)
3136 \fn test_fapi_get_random(FAPI_CONTEXT *context)
3137 \fn test_fapi_info(FAPI_CONTEXT *context)
3138 \fn test_fapi_key_change_auth(FAPI_CONTEXT *context)
3139 \fn test_fapi_key_create_ckda_sign(FAPI_CONTEXT *context)
3140 \fn test_fapi_key_create_policies_sign(FAPI_CONTEXT *context)
3141 \fn test_fapi_key_create_policy_authorize_nv(FAPI_CONTEXT *context)
3142 \fn test_fapi_key_create_policy_authorize_sign(FAPI_CONTEXT *context)
3143 \fn test_fapi_key_create_policy_nv_sign(FAPI_CONTEXT *context)
3144 \fn test_fapi_key_create_policy_or_sign(FAPI_CONTEXT *context)
3145 \fn test_fapi_key_create_policy_password_sign(FAPI_CONTEXT *context)
3146 \fn test_fapi_key_create_policy_pcr_sign(FAPI_CONTEXT *context)
3147 \fn test_fapi_key_create_policy_secret_nv_sign(FAPI_CONTEXT *context)
3148 \fn test_fapi_key_create_policy_signed(FAPI_CONTEXT *context)
3149 \fn test_fapi_key_create_sign(FAPI_CONTEXT *context)
3150 \fn test_fapi_key_create_sign_password_provision(FAPI_CONTEXT *context)
3151 \fn test_fapi_key_create_sign_policy_provision(FAPI_CONTEXT *context)
3152 \fn test_fapi_nv_extend(FAPI_CONTEXT *context)
3153 \fn test_fapi_nv_increment(FAPI_CONTEXT *context)
3154 \fn test_fapi_nv_ordinary(FAPI_CONTEXT *context)
3155 \fn test_fapi_nv_set_bits(FAPI_CONTEXT *context)
3156 \fn test_fapi_nv_written_policy(FAPI_CONTEXT *context)
3157 \fn test_fapi_pcr_test(FAPI_CONTEXT *context)
3158 \fn test_fapi_platform_certificates(FAPI_CONTEXT *context)
3159 \fn test_fapi_quote(FAPI_CONTEXT *context)
3160 \fn test_fapi_unseal(FAPI_CONTEXT *context)
3161 \}
3162 */
1313 The level can be set for all module using the `all` module name or individually
1414 per module. The environment variable is evaluated left to right.
1515
16 Example: `TSS2_LOG=all+ERROR,marshal+TRACE,tcti+DEBUG
16 Example: `TSS2_LOG=all+ERROR,marshal+TRACE,tcti+DEBUG`
1717
1818 # Implementation
1919
9494 #define TSS2_BASE_RC_MULTIPLE_DECRYPT_SESSIONS 25U /* More than one session with TPMA_SESSION_DECRYPT bit set */
9595 #define TSS2_BASE_RC_MULTIPLE_ENCRYPT_SESSIONS 26U /* More than one session with TPMA_SESSION_ENCRYPT bit set */
9696 #define TSS2_BASE_RC_RSP_AUTH_FAILED 27U /* Response HMAC from TPM did not verify */
97 #define TSS2_BASE_RC_NO_CONFIG 28U
98 #define TSS2_BASE_RC_BAD_PATH 29U
99 #define TSS2_BASE_RC_NOT_DELETABLE 30U
100 #define TSS2_BASE_RC_PATH_ALREADY_EXISTS 31U
101 #define TSS2_BASE_RC_KEY_NOT_FOUND 32U
102 #define TSS2_BASE_RC_SIGNATURE_VERIFICATION_FAILED 33U
103 #define TSS2_BASE_RC_HASH_MISMATCH 34U
104 #define TSS2_BASE_RC_KEY_NOT_DUPLICABLE 35U
105 #define TSS2_BASE_RC_PATH_NOT_FOUND 36U
106 #define TSS2_BASE_RC_NO_CERT 37U
107 #define TSS2_BASE_RC_NO_PCR 38U
108 #define TSS2_BASE_RC_PCR_NOT_RESETTABLE 39U
109 #define TSS2_BASE_RC_BAD_TEMPLATE 40U
110 #define TSS2_BASE_RC_AUTHORIZATION_FAILED 41U
111 #define TSS2_BASE_RC_AUTHORIZATION_UNKNOWN 42U
112 #define TSS2_BASE_RC_NV_NOT_READABLE 43U
113 #define TSS2_BASE_RC_NV_TOO_SMALL 44U
114 #define TSS2_BASE_RC_NV_NOT_WRITEABLE 45U
115 #define TSS2_BASE_RC_POLICY_UNKNOWN 46U
116 #define TSS2_BASE_RC_NV_WRONG_TYPE 47U
117 #define TSS2_BASE_RC_NAME_ALREADY_EXISTS 48U
118 #define TSS2_BASE_RC_NO_TPM 49U
119 #define TSS2_BASE_RC_BAD_KEY 50U
120 #define TSS2_BASE_RC_NO_HANDLE 51U
97121
98122 /* Base return codes in the range 0xf800 - 0xffff are reserved for
99123 * implementation-specific purposes.
227251 #define TSS2_ESYS_RC_RSP_AUTH_FAILED ((TSS2_RC)(TSS2_ESAPI_RC_LAYER | \
228252 TSS2_BASE_RC_RSP_AUTH_FAILED))
229253
254 /* FAPI Error Codes */
255
256 #define TSS2_FAPI_RC_GENERAL_FAILURE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
257 TSS2_BASE_RC_GENERAL_FAILURE))
258 #define TSS2_FAPI_RC_NOT_IMPLEMENTED ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
259 TSS2_BASE_RC_NOT_IMPLEMENTED))
260 #define TSS2_FAPI_RC_BAD_REFERENCE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
261 TSS2_BASE_RC_BAD_REFERENCE))
262 #define TSS2_FAPI_RC_BAD_SEQUENCE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
263 TSS2_BASE_RC_BAD_SEQUENCE))
264 #define TSS2_FAPI_RC_IO_ERROR ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
265 TSS2_BASE_RC_IO_ERROR))
266 #define TSS2_FAPI_RC_BAD_VALUE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
267 TSS2_BASE_RC_BAD_VALUE))
268 #define TSS2_FAPI_RC_NO_DECRYPT_PARAM ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
269 TSS2_BASE_RC_NO_DECRYPT_PARAM))
270 #define TSS2_FAPI_RC_NO_ENCRYPT_PARAM ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
271 TSS2_BASE_RC_NO_ENCRYPT_PARAM))
272 #define TSS2_FAPI_RC_MEMORY ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
273 TSS2_BASE_RC_MEMORY))
274 #define TSS2_FAPI_RC_BAD_CONTEXT ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
275 TSS2_BASE_RC_BAD_CONTEXT))
276 #define TSS2_FAPI_RC_NO_CONFIG ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
277 TSS2_BASE_RC_NO_CONFIG))
278 #define TSS2_FAPI_RC_BAD_PATH ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
279 TSS2_BASE_RC_BAD_PATH))
280 #define TSS2_FAPI_RC_NOT_DELETABLE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
281 TSS2_BASE_RC_NOT_DELETABLE))
282 #define TSS2_FAPI_RC_PATH_ALREADY_EXISTS ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
283 TSS2_BASE_RC_PATH_ALREADY_EXISTS))
284 #define TSS2_FAPI_RC_KEY_NOT_FOUND ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
285 TSS2_BASE_RC_KEY_NOT_FOUND))
286 #define TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
287 TSS2_BASE_RC_SIGNATURE_VERIFICATION_FAILED))
288 #define TSS2_FAPI_RC_HASH_MISMATCH ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
289 TSS2_BASE_RC_HASH_MISMATCH))
290 #define TSS2_FAPI_RC_KEY_NOT_DUPLICABLE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
291 TSS2_BASE_RC_KEY_NOT_DUPLICABLE))
292 #define TSS2_FAPI_RC_PATH_NOT_FOUND ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
293 TSS2_BASE_RC_PATH_NOT_FOUND))
294 #define TSS2_FAPI_RC_NO_CERT ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
295 TSS2_BASE_RC_NO_CERT))
296 #define TSS2_FAPI_RC_NO_PCR ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
297 TSS2_BASE_RC_NO_PCR))
298 #define TSS2_FAPI_RC_PCR_NOT_RESETTABLE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
299 TSS2_BASE_RC_PCR_NOT_RESETTABLE))
300 #define TSS2_FAPI_RC_BAD_TEMPLATE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
301 TSS2_BASE_RC_BAD_TEMPLATE))
302 #define TSS2_FAPI_RC_AUTHORIZATION_FAILED ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
303 TSS2_BASE_RC_AUTHORIZATION_FAILED))
304 #define TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
305 TSS2_BASE_RC_AUTHORIZATION_UNKNOWN))
306 #define TSS2_FAPI_RC_NV_NOT_READABLE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
307 TSS2_BASE_RC_NV_NOT_READABLE))
308 #define TSS2_FAPI_RC_NV_TOO_SMALL ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
309 TSS2_BASE_RC_NV_TOO_SMALL))
310 #define TSS2_FAPI_RC_NV_NOT_WRITEABLE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
311 TSS2_BASE_RC_NV_NOT_WRITEABLE))
312 #define TSS2_FAPI_RC_POLICY_UNKNOWN ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
313 TSS2_BASE_RC_POLICY_UNKNOWN))
314 #define TSS2_FAPI_RC_NV_WRONG_TYPE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
315 TSS2_BASE_RC_NV_WRONG_TYPE))
316 #define TSS2_FAPI_RC_NAME_ALREADY_EXISTS ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
317 TSS2_BASE_RC_NAME_ALREADY_EXISTS))
318 #define TSS2_FAPI_RC_NO_TPM ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
319 TSS2_BASE_RC_NO_TPM))
320 #define TSS2_FAPI_RC_TRY_AGAIN ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
321 TSS2_BASE_RC_TRY_AGAIN))
322 #define TSS2_FAPI_RC_BAD_KEY ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
323 TSS2_BASE_RC_BAD_KEY))
324 #define TSS2_FAPI_RC_NO_HANDLE ((TSS2_RC)(TSS2_FEATURE_RC_LAYER | \
325 TSS2_BASE_RC_NO_HANDLE))
230326 #endif /* TSS2_COMMON_H */
166166 ESYS_TR session,
167167 TPM2B_NONCE **nonceTPM);
168168
169 TSS2_RC
170 Esys_TR_GetTpmHandle(
171 ESYS_CONTEXT *esys_context,
172 ESYS_TR esys_handle,
173 TPM2_HANDLE *tpm_handle);
174
175 TSS2_RC
176 Esys_TRSess_GetAuthRequired(
177 ESYS_CONTEXT *esys_context,
178 ESYS_TR esys_handle,
179 TPMI_YES_NO *auth_needed);
180
169181 /* Table 5 - TPM2_Startup Command */
170182
171183 TSS2_RC
32273239 Esys_Free(
32283240 void *__ptr);
32293241
3242 TSS2_RC
3243 Esys_GetSysContext(
3244 ESYS_CONTEXT *esys_context,
3245 TSS2_SYS_CONTEXT **sys_context);
3246
32303247 #ifdef __cplusplus
32313248 }
32323249 #endif
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef TSS2_FAPI_H
6 #define TSS2_FAPI_H
7
8 #include "tss2_tcti.h"
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 /* Type definitions */
15
16 typedef struct FAPI_CONTEXT FAPI_CONTEXT;
17
18 /* Context functions */
19
20 TSS2_RC Fapi_Initialize(
21 FAPI_CONTEXT **context,
22 char const *uri);
23
24 TSS2_RC Fapi_Initialize_Async(
25 FAPI_CONTEXT **context,
26 char const *uri);
27
28 TSS2_RC Fapi_Initialize_Finish(
29 FAPI_CONTEXT **context);
30
31 void Fapi_Finalize(
32 FAPI_CONTEXT **context);
33
34 TSS2_RC Fapi_GetTcti(
35 FAPI_CONTEXT *context,
36 TSS2_TCTI_CONTEXT **tcti);
37
38 void Fapi_Free(
39 void *ptr);
40
41 #if defined(__linux__) || defined(__unix__) || defined(__APPLE__) || defined (__QNXNTO__) || defined (__VXWORKS__)
42 #if defined (__VXWORKS__)
43 #include <sys/poll.h>
44 #else
45 #include <poll.h>
46 #endif
47 typedef struct pollfd FAPI_POLL_HANDLE;
48 #elif defined(_WIN32)
49 #include <windows.h>
50 typedef HANDLE FAPI_POLL_HANDLE;
51 #else
52 typedef void FAPI_POLL_HANDLE;
53 #ifndef FAPI_SUPPRESS_POLL_WARNINGS
54 #pragma message "Info: Platform not supported for FAPI_POLL_HANDLES"
55 #endif
56 #endif
57
58 TSS2_RC Fapi_GetPollHandles(
59 FAPI_CONTEXT *context,
60 FAPI_POLL_HANDLE **handles,
61 size_t *num_handles);
62
63 TSS2_RC Fapi_GetInfo(
64 FAPI_CONTEXT *context,
65 char **info);
66
67 TSS2_RC Fapi_GetInfo_Async(
68 FAPI_CONTEXT *context);
69
70 TSS2_RC Fapi_GetInfo_Finish(
71 FAPI_CONTEXT *context,
72 char **info);
73
74 /* General functions */
75
76 TSS2_RC Fapi_Provision(
77 FAPI_CONTEXT *context,
78 char const *authValueEh,
79 char const *authValueSh,
80 char const *authValueLockout);
81
82 TSS2_RC Fapi_Provision_Async(
83 FAPI_CONTEXT *context,
84 char const *authValueEh,
85 char const *authValueSh,
86 char const *authValueLockout);
87
88 TSS2_RC Fapi_Provision_Finish(
89 FAPI_CONTEXT *context);
90
91 TSS2_RC Fapi_GetPlatformCertificates(
92 FAPI_CONTEXT *context,
93 uint8_t **certificates,
94 size_t *certificatesSize);
95
96 TSS2_RC Fapi_GetPlatformCertificates_Async(
97 FAPI_CONTEXT *context);
98
99 TSS2_RC Fapi_GetPlatformCertificates_Finish(
100 FAPI_CONTEXT *context,
101 uint8_t **certificates,
102 size_t *certificatesSize);
103
104 TSS2_RC Fapi_GetRandom(
105 FAPI_CONTEXT *context,
106 size_t numBytes,
107 uint8_t **data);
108
109 TSS2_RC Fapi_GetRandom_Async(
110 FAPI_CONTEXT *context,
111 size_t numBytes);
112
113 TSS2_RC Fapi_GetRandom_Finish(
114 FAPI_CONTEXT *context,
115 uint8_t **data);
116
117 TSS2_RC Fapi_Import(
118 FAPI_CONTEXT *context,
119 char const *path,
120 char const *importData);
121
122 TSS2_RC Fapi_Import_Async(
123 FAPI_CONTEXT *context,
124 char const *path,
125 char const *importData);
126
127 TSS2_RC Fapi_Import_Finish(
128 FAPI_CONTEXT *context);
129
130 TSS2_RC Fapi_List(
131 FAPI_CONTEXT *context,
132 char const *searchPath,
133 char **pathList);
134
135 TSS2_RC Fapi_List_Async(
136 FAPI_CONTEXT *context,
137 char const *searchPath);
138
139 TSS2_RC Fapi_List_Finish(
140 FAPI_CONTEXT *context,
141 char **pathList);
142
143 TSS2_RC Fapi_Delete(
144 FAPI_CONTEXT *context,
145 char const *path);
146
147 TSS2_RC Fapi_Delete_Async(
148 FAPI_CONTEXT *context,
149 char const *path);
150
151 TSS2_RC Fapi_Delete_Finish(
152 FAPI_CONTEXT *context);
153
154 TSS2_RC Fapi_ChangeAuth(
155 FAPI_CONTEXT *context,
156 char const *entityPath,
157 char const *authValue);
158
159 TSS2_RC Fapi_ChangeAuth_Async(
160 FAPI_CONTEXT *context,
161 char const *entityPath,
162 char const *authValue);
163
164 TSS2_RC Fapi_ChangeAuth_Finish(
165 FAPI_CONTEXT *context);
166
167 TSS2_RC Fapi_SetDescription(
168 FAPI_CONTEXT *context,
169 char const *path,
170 char const *description);
171
172 TSS2_RC Fapi_SetDescription_Async(
173 FAPI_CONTEXT *context,
174 char const *path,
175 char const *description);
176
177 TSS2_RC Fapi_SetDescription_Finish(
178 FAPI_CONTEXT *context);
179
180 TSS2_RC Fapi_GetDescription(
181 FAPI_CONTEXT *context,
182 char const *path,
183 char **description);
184
185 TSS2_RC Fapi_GetDescription_Async(
186 FAPI_CONTEXT *context,
187 char const *path);
188
189 TSS2_RC Fapi_GetDescription_Finish(
190 FAPI_CONTEXT *context,
191 char **description);
192
193 TSS2_RC Fapi_SetAppData(
194 FAPI_CONTEXT *context,
195 char const *path,
196 uint8_t const *appData,
197 size_t appDataSize);
198
199 TSS2_RC Fapi_SetAppData_Async(
200 FAPI_CONTEXT *context,
201 char const *path,
202 uint8_t const *appData,
203 size_t appDataSize);
204
205 TSS2_RC Fapi_SetAppData_Finish(
206 FAPI_CONTEXT *context);
207
208 TSS2_RC Fapi_GetAppData(
209 FAPI_CONTEXT *context,
210 char const *path,
211 uint8_t **appData,
212 size_t *appDataSize);
213
214 TSS2_RC Fapi_GetAppData_Async(
215 FAPI_CONTEXT *context,
216 char const *path);
217
218 TSS2_RC Fapi_GetAppData_Finish(
219 FAPI_CONTEXT *context,
220 uint8_t **appData,
221 size_t *appDataSize);
222
223 TSS2_RC Fapi_GetTpmBlobs(
224 FAPI_CONTEXT *context,
225 char const *path,
226 uint8_t **tpm2bPublic,
227 size_t *tpm2bPublicSize,
228 uint8_t **tpm2bPrivate,
229 size_t *tpm2bPrivateSize,
230 char **policy);
231
232 TSS2_RC Fapi_GetTpmBlobs_Async(
233 FAPI_CONTEXT *context,
234 char const *path);
235
236 TSS2_RC Fapi_GetTpmBlobs_Finish(
237 FAPI_CONTEXT *context,
238 uint8_t **tpm2bPublic,
239 size_t *tpm2bPublicSize,
240 uint8_t **tpm2bPrivate,
241 size_t *tpm2bPrivateSize,
242 char **policy);
243
244 /* Key functions */
245
246 TSS2_RC Fapi_CreateKey(
247 FAPI_CONTEXT *context,
248 char const *path,
249 char const *type,
250 char const *policyPath,
251 char const *authValue);
252
253 TSS2_RC Fapi_CreateKey_Async(
254 FAPI_CONTEXT *context,
255 char const *path,
256 char const *type,
257 char const *policyPath,
258 char const *authValue);
259
260 TSS2_RC Fapi_CreateKey_Finish(
261 FAPI_CONTEXT *context);
262
263 TSS2_RC Fapi_Sign(
264 FAPI_CONTEXT *context,
265 char const *keyPath,
266 char const *padding,
267 uint8_t const *digest,
268 size_t digestSize,
269 uint8_t **signature,
270 size_t *signatureSize,
271 char **publicKey,
272 char **certificate);
273
274 TSS2_RC Fapi_Sign_Async(
275 FAPI_CONTEXT *context,
276 char const *keyPath,
277 char const *padding,
278 uint8_t const *digest,
279 size_t digestSize);
280
281 TSS2_RC Fapi_Sign_Finish(
282 FAPI_CONTEXT *context,
283 uint8_t **signature,
284 size_t *signatureSize,
285 char **publicKey,
286 char **certificate);
287
288 TSS2_RC Fapi_VerifySignature(
289 FAPI_CONTEXT *context,
290 char const *keyPath,
291 uint8_t const *digest,
292 size_t digestSize,
293 uint8_t const *signature,
294 size_t signatureSize);
295
296 TSS2_RC Fapi_VerifySignature_Async(
297 FAPI_CONTEXT *context,
298 char const *keyPath,
299 uint8_t const *digest,
300 size_t digestSize,
301 uint8_t const *signature,
302 size_t signatureSize);
303
304 TSS2_RC Fapi_VerifySignature_Finish(
305 FAPI_CONTEXT *context);
306
307 TSS2_RC Fapi_Encrypt(
308 FAPI_CONTEXT *context,
309 char const *keyPath,
310 uint8_t const *plainText,
311 size_t plainTextSize,
312 uint8_t **cipherText,
313 size_t *cipherTextSize);
314
315 TSS2_RC Fapi_Encrypt_Async(
316 FAPI_CONTEXT *context,
317 char const *keyPath,
318 uint8_t const *plainText,
319 size_t plainTextSize);
320
321 TSS2_RC Fapi_Encrypt_Finish(
322 FAPI_CONTEXT *context,
323 uint8_t **cipherText,
324 size_t *cipherTextSize );
325
326 TSS2_RC Fapi_Decrypt(
327 FAPI_CONTEXT *context,
328 char const *keyPath,
329 uint8_t const *cipherText,
330 size_t cipherTextSize,
331 uint8_t **plainText,
332 size_t *plainTextSize);
333
334 TSS2_RC Fapi_Decrypt_Async(
335 FAPI_CONTEXT *context,
336 char const *keyPath,
337 uint8_t const *cipherText,
338 size_t cipherTextSize);
339
340 TSS2_RC Fapi_Decrypt_Finish(
341 FAPI_CONTEXT *context,
342 uint8_t **plainText,
343 size_t *plainTextSize);
344
345 TSS2_RC Fapi_SetCertificate(
346 FAPI_CONTEXT *context,
347 char const *path,
348 char const *x509certData);
349
350 TSS2_RC Fapi_SetCertificate_Async(
351 FAPI_CONTEXT *context,
352 char const *path,
353 char const *x509certData);
354
355 TSS2_RC Fapi_SetCertificate_Finish(
356 FAPI_CONTEXT *context);
357
358 TSS2_RC Fapi_GetCertificate(
359 FAPI_CONTEXT *context,
360 char const *path,
361 char **x509certData);
362
363 TSS2_RC Fapi_GetCertificate_Async(
364 FAPI_CONTEXT *context,
365 char const *path);
366
367 TSS2_RC Fapi_GetCertificate_Finish(
368 FAPI_CONTEXT *context,
369 char **x509certData);
370
371 TSS2_RC Fapi_ExportKey(
372 FAPI_CONTEXT *context,
373 char const *pathOfKeyToDuplicate,
374 char const *pathToPublicKeyOfNewParent,
375 char **exportedData);
376
377 TSS2_RC Fapi_ExportKey_Async(
378 FAPI_CONTEXT *context,
379 char const *pathOfKeyToDuplicate,
380 char const *pathToPublicKeyOfNewParent);
381
382 TSS2_RC Fapi_ExportKey_Finish(
383 FAPI_CONTEXT *context,
384 char **exportedData);
385
386 /* Seal functions */
387
388 TSS2_RC Fapi_CreateSeal(
389 FAPI_CONTEXT *context,
390 char const *path,
391 char const *type,
392 size_t size,
393 char const *policyPath,
394 char const *authValue,
395 uint8_t const *data);
396
397 TSS2_RC Fapi_CreateSeal_Async(
398 FAPI_CONTEXT *context,
399 char const *path,
400 char const *type,
401 size_t size,
402 char const *policyPath,
403 char const *authValue,
404 uint8_t const *data);
405
406 TSS2_RC Fapi_CreateSeal_Finish(
407 FAPI_CONTEXT *context);
408
409 TSS2_RC Fapi_Unseal(
410 FAPI_CONTEXT *context,
411 char const *path,
412 uint8_t **data,
413 size_t *size);
414
415 TSS2_RC Fapi_Unseal_Async(
416 FAPI_CONTEXT *context,
417 char const *path);
418
419 TSS2_RC Fapi_Unseal_Finish(
420 FAPI_CONTEXT *context,
421 uint8_t **data,
422 size_t *size);
423
424 /* Policy functions */
425
426 TSS2_RC Fapi_ExportPolicy(
427 FAPI_CONTEXT *context,
428 char const *path,
429 char **jsonPolicy);
430
431 TSS2_RC Fapi_ExportPolicy_Async(
432 FAPI_CONTEXT *context,
433 char const *path);
434
435 TSS2_RC Fapi_ExportPolicy_Finish(
436 FAPI_CONTEXT *context,
437 char **jsonPolicy);
438
439 TSS2_RC Fapi_AuthorizePolicy(
440 FAPI_CONTEXT *context,
441 char const *policyPath,
442 char const *keyPath,
443 uint8_t const *policyRef,
444 size_t policyRefSize);
445
446 TSS2_RC Fapi_AuthorizePolicy_Async(
447 FAPI_CONTEXT *context,
448 char const *policyPath,
449 char const *keyPath,
450 uint8_t const *policyRef,
451 size_t policyRefSize);
452
453 TSS2_RC Fapi_AuthorizePolicy_Finish(
454 FAPI_CONTEXT *context);
455
456 TSS2_RC Fapi_WriteAuthorizeNv(
457 FAPI_CONTEXT *context,
458 char const *nvPath,
459 char const *policyPath);
460
461 TSS2_RC Fapi_WriteAuthorizeNv_Async(
462 FAPI_CONTEXT *context,
463 char const *nvPath,
464 char const *policyPath);
465
466 TSS2_RC Fapi_WriteAuthorizeNv_Finish(
467 FAPI_CONTEXT *context);
468
469 /* Attestation functions */
470
471 TSS2_RC Fapi_PcrRead(
472 FAPI_CONTEXT *context,
473 uint32_t pcrIndex,
474 uint8_t **pcrValue,
475 size_t *pcrValueSize,
476 char **pcrLog);
477
478 TSS2_RC Fapi_PcrRead_Async(
479 FAPI_CONTEXT *context,
480 uint32_t pcrIndex);
481
482 TSS2_RC Fapi_PcrRead_Finish(
483 FAPI_CONTEXT *context,
484 uint8_t **pcrValue,
485 size_t *pcrValueSize,
486 char **pcrLog);
487
488 TSS2_RC Fapi_PcrExtend(
489 FAPI_CONTEXT *context,
490 uint32_t pcr,
491 uint8_t const *data,
492 size_t dataSize,
493 char const *logData);
494
495 TSS2_RC Fapi_PcrExtend_Async(
496 FAPI_CONTEXT *context,
497 uint32_t pcr,
498 uint8_t const *data,
499 size_t dataSize,
500 char const *logData);
501
502 TSS2_RC Fapi_PcrExtend_Finish(
503 FAPI_CONTEXT *context);
504
505
506 TSS2_RC Fapi_Quote(
507 FAPI_CONTEXT *context,
508 uint32_t *pcrList,
509 size_t pcrListSize,
510 char const *keyPath,
511 char const *quoteType,
512 uint8_t const *qualifyingData,
513 size_t qualifyingDataSize,
514 char **quoteInfo,
515 uint8_t **signature,
516 size_t *signatureSize,
517 char **pcrLog,
518 char **certificate);
519
520 TSS2_RC Fapi_Quote_Async(
521 FAPI_CONTEXT *context,
522 uint32_t *pcrList,
523 size_t pcrListSize,
524 char const *keyPath,
525 char const *quoteType,
526 uint8_t const *qualifyingData,
527 size_t qualifyingDataSize);
528
529 TSS2_RC Fapi_Quote_Finish(
530 FAPI_CONTEXT *context,
531 char **quoteInfo,
532 uint8_t **signature,
533 size_t *signatureSize,
534 char **pcrLog,
535 char **certificate);
536
537 TSS2_RC Fapi_VerifyQuote(
538 FAPI_CONTEXT *context,
539 char const *publicKeyPath,
540 uint8_t const *qualifyingData,
541 size_t qualifyingDataSize,
542 char const *quoteInfo,
543 uint8_t const *signature,
544 size_t signatureSize,
545 char const *pcrLog);
546
547 TSS2_RC Fapi_VerifyQuote_Async(
548 FAPI_CONTEXT *context,
549 char const *publicKeyPath,
550 uint8_t const *qualifyingData,
551 size_t qualifyingDataSize,
552 char const *quoteInfo,
553 uint8_t const *signature,
554 size_t signatureSize,
555 char const *pcrLog);
556
557 TSS2_RC Fapi_VerifyQuote_Finish(
558 FAPI_CONTEXT *context);
559
560 /* NV functions */
561
562 TSS2_RC Fapi_CreateNv(
563 FAPI_CONTEXT *context,
564 char const *path,
565 char const *type,
566 size_t size,
567 char const *policyPath,
568 char const *authValue);
569
570 TSS2_RC Fapi_CreateNv_Async(
571 FAPI_CONTEXT *context,
572 char const *path,
573 char const *type,
574 size_t size,
575 char const *policyPath,
576 char const *authValue);
577
578 TSS2_RC Fapi_CreateNv_Finish(
579 FAPI_CONTEXT *context);
580
581 TSS2_RC Fapi_NvRead(
582 FAPI_CONTEXT *context,
583 char const *path,
584 uint8_t **data,
585 size_t *size,
586 char **logData);
587
588 TSS2_RC Fapi_NvRead_Async(
589 FAPI_CONTEXT *context,
590 char const *path);
591
592 TSS2_RC Fapi_NvRead_Finish(
593 FAPI_CONTEXT *context,
594 uint8_t **data,
595 size_t *size,
596 char **logData);
597
598 TSS2_RC Fapi_NvWrite(
599 FAPI_CONTEXT *context,
600 char const *path,
601 uint8_t const *data,
602 size_t size);
603
604 TSS2_RC Fapi_NvWrite_Async(
605 FAPI_CONTEXT *context,
606 char const *path,
607 uint8_t const *data,
608 size_t size);
609
610 TSS2_RC Fapi_NvWrite_Finish(
611 FAPI_CONTEXT *context);
612
613 TSS2_RC Fapi_NvExtend(
614 FAPI_CONTEXT *context,
615 char const *path,
616 uint8_t const *data,
617 size_t size,
618 char const *logData);
619
620 TSS2_RC Fapi_NvExtend_Async(
621 FAPI_CONTEXT *context,
622 char const *path,
623 uint8_t const *data,
624 size_t size,
625 char const *logData);
626
627 TSS2_RC Fapi_NvExtend_Finish(
628 FAPI_CONTEXT *context);
629
630 TSS2_RC Fapi_NvIncrement(
631 FAPI_CONTEXT *context,
632 char const *path);
633
634 TSS2_RC Fapi_NvIncrement_Async(
635 FAPI_CONTEXT *context,
636 char const *path);
637
638 TSS2_RC Fapi_NvIncrement_Finish(
639 FAPI_CONTEXT *context);
640
641 TSS2_RC Fapi_NvSetBits(
642 FAPI_CONTEXT *context,
643 char const *path,
644 uint64_t bitmap);
645
646 TSS2_RC Fapi_NvSetBits_Async(
647 FAPI_CONTEXT *context,
648 char const *path,
649 uint64_t bitmap);
650
651 TSS2_RC Fapi_NvSetBits_Finish(
652 FAPI_CONTEXT *context);
653
654 typedef TSS2_RC (*Fapi_CB_Auth)(
655 FAPI_CONTEXT *context,
656 char const *description,
657 char **auth,
658 void *userData);
659
660 TSS2_RC Fapi_SetAuthCB(
661 FAPI_CONTEXT *context,
662 Fapi_CB_Auth callback,
663 void *userData);
664
665 typedef TSS2_RC (*Fapi_CB_Branch)(
666 FAPI_CONTEXT *context,
667 char const *description,
668 char const **branchNames,
669 size_t numBranches,
670 size_t *selectedBranch,
671 void *userData);
672
673 TSS2_RC Fapi_SetBranchCB(
674 FAPI_CONTEXT *context,
675 Fapi_CB_Branch callback,
676 void *userData);
677
678 typedef TSS2_RC (*Fapi_CB_Sign)(
679 FAPI_CONTEXT *context,
680 char const *description,
681 char const *publicKey,
682 char const *publicKeyHint,
683 uint32_t hashAlg,
684 uint8_t const *dataToSign,
685 size_t dataToSignSize,
686 uint8_t **signature,
687 size_t *signatureSize,
688 void *userData);
689
690 TSS2_RC Fapi_SetSignCB(
691 FAPI_CONTEXT *context,
692 Fapi_CB_Sign callback,
693 void *userData);
694
695 typedef TSS2_RC (*Fapi_CB_PolicyAction)(
696 FAPI_CONTEXT *context,
697 char const *action,
698 void *userData);
699
700 TSS2_RC Fapi_SetPolicyActionCB(
701 FAPI_CONTEXT *context,
702 Fapi_CB_PolicyAction callback,
703 void *userData);
704
705 #ifdef __cplusplus
706 }
707 #endif
708
709 #endif /* TSS2_FAPI_H */
66
77 #include "tss2_tpm2_types.h"
88
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
913 typedef const char *(*TSS2_RC_HANDLER)(TSS2_RC rc);
1014
1115 const char *Tss2_RC_Decode(TSS2_RC rc);
1216
1317 TSS2_RC_HANDLER Tss2_RC_SetHandler(uint8_t layer, const char *name, TSS2_RC_HANDLER handler);
1418
19 #ifdef __cplusplus
20 }
1521 #endif
22
23 #endif
7070
7171 #define TPM2_ALG_ERROR ((TPM2_ALG_ID) 0x0000)
7272 #define TPM2_ALG_RSA ((TPM2_ALG_ID) 0x0001)
73 #define TPM2_ALG_TDES ((TPM2_ALG_ID) 0x0003)
7374 #define TPM2_ALG_SHA ((TPM2_ALG_ID) 0x0004)
7475 #define TPM2_ALG_SHA1 ((TPM2_ALG_ID) 0x0004)
7576 #define TPM2_ALG_HMAC ((TPM2_ALG_ID) 0x0005)
481482 #define TPM2_PT_FIRMWARE_VERSION_1 ((TPM2_PT) (TPM2_PT_FIXED + 11)) /* the most significant 32 bits of a TPM vendor-specific value indicating the version number of the firmware. See 10.12.2 and 10.12.8. */
482483 #define TPM2_PT_FIRMWARE_VERSION_2 ((TPM2_PT) (TPM2_PT_FIXED + 12)) /* the least significant 32 bits of a TPM vendor-specific value indicating the version number of the firmware. See 10.12.2 and 10.12.8. */
483484 #define TPM2_PT_INPUT_BUFFER ((TPM2_PT) (TPM2_PT_FIXED + 13)) /* the maximum size of a parameter typically a TPM2B_MAX_BUFFER */
484 #define TPM2_PT_TPM2_HR_TRANSIENT_MIN ((TPM2_PT) (TPM2_PT_FIXED + 14)) /* the minimum number of transient objects that can be held in TPM RAM. NOTE This minimum shall be no less than the minimum value required by the platforms-pecific specification to which the TPM is built. */
485 #define TPM2_PT_TPM2_HR_PERSISTENT_MIN ((TPM2_PT) (TPM2_PT_FIXED + 15)) /* the minimum number of persistent objects that can be held in TPM NV memory. NOTE This minimum shall be no less than the minimum value required by the platform-specific specification to which the TPM is built. */
485 #define TPM2_PT_HR_TRANSIENT_MIN ((TPM2_PT) (TPM2_PT_FIXED + 14)) /* the minimum number of transient objects that can be held in TPM RAM. NOTE This minimum shall be no less than the minimum value required by the platforms-pecific specification to which the TPM is built. */
486 #define TPM2_PT_HR_PERSISTENT_MIN ((TPM2_PT) (TPM2_PT_FIXED + 15)) /* the minimum number of persistent objects that can be held in TPM NV memory. NOTE This minimum shall be no less than the minimum value required by the platform-specific specification to which the TPM is built. */
486487 #define TPM2_PT_HR_LOADED_MIN ((TPM2_PT) (TPM2_PT_FIXED + 16)) /* the minimum number of authorization sessions that can be held in TPM RAM . NOTE This minimum shall be no less than the minimum value required by the platform-specific specification to which the TPM is built. */
487488 #define TPM2_PT_ACTIVE_SESSIONS_MAX ((TPM2_PT) (TPM2_PT_FIXED + 17)) /* the number of authorization sessions that may be active at a time. A session is active when it has a context associated with its handle. The context may either be in TPM RAM or be context saved. NOTE This value shall be no less than the minimum value required by the platform-specific specification to which the TPM is built. */
488489 #define TPM2_PT_PCR_COUNT ((TPM2_PT) (TPM2_PT_FIXED + 18)) /* the number of PCR implemented. NOTE This number is determined by the defined attributes not the number of PCR that are populated. */
512513 #define TPM2_PT_VENDOR_COMMANDS ((TPM2_PT) (TPM2_PT_FIXED + 43)) /* number of vendor commands that are implemented */
513514 #define TPM2_PT_NV_BUFFER_MAX ((TPM2_PT) (TPM2_PT_FIXED + 44)) /* the maximum data size in one NV write command */
514515 #define TPM2_PT_MODES ((TPM2_PT) (TPM2_PT_FIXED + 45)) /* a TPMA_MODES value indicating that the TPM is designed for these modes. */
516 #define TPM2_PT_MAX_CAP_BUFFER ((TPM2_PT) (TPM2_PT_FIXED + 46)) /* the maximum size of a TPMS_CAPABILITY_DATA structure returned in TPM2_GetCapability(). */
515517 #define TPM2_PT_VAR ((TPM2_PT) (TPM2_PT_GROUP * 2)) /* the group of variable properties returned as TPMS_TAGGED_PROPERTY. The properties in this group change because of a Protected Capability other than a firmware update. The values are not necessarily persistent across all power transitions. */
516518 #define TPM2_PT_PERMANENT ((TPM2_PT) (TPM2_PT_VAR + 0)) /* TPMA_PERMANENT */
517519 #define TPM2_PT_STARTUP_CLEAR ((TPM2_PT) (TPM2_PT_VAR + 1)) /* TPMA_STARTUP_CLEAR */
518 #define TPM2_PT_TPM2_HR_NV_INDEX ((TPM2_PT) (TPM2_PT_VAR + 2)) /* the number of NV Indexes currently defined */
520 #define TPM2_PT_HR_NV_INDEX ((TPM2_PT) (TPM2_PT_VAR + 2)) /* the number of NV Indexes currently defined */
519521 #define TPM2_PT_HR_LOADED ((TPM2_PT) (TPM2_PT_VAR + 3)) /* the number of authorization sessions currently loaded into TPM RAM */
520522 #define TPM2_PT_HR_LOADED_AVAIL ((TPM2_PT) (TPM2_PT_VAR + 4)) /* the number of additional authorization sessions of any type that could be loaded into TPM RAM. This value is an estimate. If this value is at least 1 then at least one authorization session of any type may be loaded. Any command that changes the RAM memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one authorization session would fit into RAM. */
521523 #define TPM2_PT_HR_ACTIVE ((TPM2_PT) (TPM2_PT_VAR + 5)) /* the number of active authorization sessions currently being tracked by the TPMThis is the sum of the loaded and saved sessions. */
522524 #define TPM2_PT_HR_ACTIVE_AVAIL ((TPM2_PT) (TPM2_PT_VAR + 6)) /* the number of additional authorization sessions of any type that could be created. This value is an estimate. If this value is at least 1 then at least one authorization session of any type may be created. Any command that changes the RAM memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one authorization session could be created. */
523 #define TPM2_PT_TPM2_HR_TRANSIENT_AVAIL ((TPM2_PT) (TPM2_PT_VAR + 7)) /* estimate of the number of additional transient objects that could be loaded into TPM RAM. This value is an estimate. If this value is at least 1 then at least one object of any type may be loaded. Any command that changes the memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one transient object would fit into RAM. */
524 #define TPM2_PT_TPM2_HR_PERSISTENT ((TPM2_PT) (TPM2_PT_VAR + 8)) /* the number of persistent objects currently loaded into TPM NV memory */
525 #define TPM2_PT_TPM2_HR_PERSISTENT_AVAIL ((TPM2_PT) (TPM2_PT_VAR + 9)) /* the number of additional persistent objects that could be loaded into NV memory. This value is an estimate. If this value is at least 1 then at least one object of any type may be made persistent. Any command that changes the NV memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one persistent object would fit into NV memory. */
525 #define TPM2_PT_HR_TRANSIENT_AVAIL ((TPM2_PT) (TPM2_PT_VAR + 7)) /* estimate of the number of additional transient objects that could be loaded into TPM RAM. This value is an estimate. If this value is at least 1 then at least one object of any type may be loaded. Any command that changes the memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one transient object would fit into RAM. */
526 #define TPM2_PT_HR_PERSISTENT ((TPM2_PT) (TPM2_PT_VAR + 8)) /* the number of persistent objects currently loaded into TPM NV memory */
527 #define TPM2_PT_HR_PERSISTENT_AVAIL ((TPM2_PT) (TPM2_PT_VAR + 9)) /* the number of additional persistent objects that could be loaded into NV memory. This value is an estimate. If this value is at least 1 then at least one object of any type may be made persistent. Any command that changes the NV memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one persistent object would fit into NV memory. */
526528 #define TPM2_PT_NV_COUNTERS ((TPM2_PT) (TPM2_PT_VAR + 10)) /* the number of defined NV Indexes that have NV the TPM2_NT_COUNTER attribute */
527529 #define TPM2_PT_NV_COUNTERS_AVAIL ((TPM2_PT) (TPM2_PT_VAR + 11)) /* the number of additional NV Indexes that can be defined with their TPM2_NT of TPM_NV_COUNTER and the TPMA_NV_ORDERLY attribute SET. This value is an estimate. If this value is at least 1 then at least one NV Index may be created with a TPM2_NT of TPM_NV_COUNTER and the TPMA_NV_ORDERLY attributes. Any command that changes the NV memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one NV counter could be defined. */
528530 #define TPM2_PT_ALGORITHM_SET ((TPM2_PT) (TPM2_PT_VAR + 12)) /* code that limits the algorithms that may be used with the TPM */
537539
538540 /* Definition of UINT32 TPM2_PT_PCR Constants <INOUT S> */
539541 typedef UINT32 TPM2_PT_PCR;
540 #define TPM2_PT_TPM2_PCR_FIRST ((TPM2_PT_PCR) 0x00000000) /* bottom of the range of TPM2_PT_PCR properties */
542 #define TPM2_PT_TPM2_PCR_FIRST ((TPM2_PT_PCR) 0x00000000) /* bottom of the range of TPM2_PT_PCR properties */
541543 #define TPM2_PT_PCR_SAVE ((TPM2_PT_PCR) 0x00000000) /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is saved and restored by TPM2_SU_STATE */
542544 #define TPM2_PT_PCR_EXTEND_L0 ((TPM2_PT_PCR) 0x00000001) /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be extended from locality 0This property is only present if a locality other than 0 is implemented. */
543545 #define TPM2_PT_PCR_RESET_L0 ((TPM2_PT_PCR) 0x00000002) /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset by TPM2_PCR_Reset from locality 0 */
559561 #define TPM2_PT_PCR_DRTM_RESET ((TPM2_PT_PCR) 0x00000012) /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is reset by a DRTM event. These PCR are reset to 1 on TPM2_Startup and reset to 0 on a _TPM_Hash_End event following a _TPM_Hash_Start event. */
560562 #define TPM2_PT_PCR_POLICY ((TPM2_PT_PCR) 0x00000013) /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is controlled by policy. This property is only present if the TPM supports policy control of a PCR. */
561563 #define TPM2_PT_PCR_AUTH ((TPM2_PT_PCR) 0x00000014) /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is controlled by an authorization value. This property is only present if the TPM supports authorization control of a PCR. */
562 #define TPM2_PT_TPM2_PCR_LAST ((TPM2_PT_PCR) 0x00000014) /* top of the range of TPM2_PT_PCR properties of the implementation. If the TPM receives a request for a PCR property with a value larger than this the TPM will return a zero length list and set the moreData parameter to NO. NOTE This is an implementation-specific value. The value shown reflects the reference code implementation. */
564 #define TPM2_PT_TPM2_PCR_LAST ((TPM2_PT_PCR) 0x00000014) /* top of the range of TPM2_PT_PCR properties of the implementation. If the TPM receives a request for a PCR property with a value larger than this the TPM will return a zero length list and set the moreData parameter to NO. NOTE This is an implementation-specific value. The value shown reflects the reference code implementation. */
563565 /* NOTE: The following values are reserved:
564566 * 0x00000015 is reserved for the next 2nd TPM2_PT_PCR_POLICY set.
565567 * 0x00000016 is reserved for the next 2nd TPM2_PT_PCR_AUTH set.
12071209 /* Definition of SM4 TPM2_KEY_BITS TPMI_SM4_KEY_BITS Type */
12081210 typedef TPM2_KEY_BITS TPMI_SM4_KEY_BITS;
12091211
1210 /* Definition of CAMELLIA TPM2_KEY_BITS TPMI_TPM2_CAMELLIA_KEY_BITS Type */
1211 typedef TPM2_KEY_BITS TPMI_TPM2_CAMELLIA_KEY_BITS;
1212 /* Definition of CAMELLIA TPM2_KEY_BITS TPMI_CAMELLIA_KEY_BITS Type */
1213 typedef TPM2_KEY_BITS TPMI_CAMELLIA_KEY_BITS;
12121214
12131215 /* Definition of TPMU_SYM_KEY_BITS Union */
12141216 typedef union {
12151217 TPMI_AES_KEY_BITS aes; /* all symmetric algorithms */
12161218 TPMI_SM4_KEY_BITS sm4; /* all symmetric algorithms */
1217 TPMI_TPM2_CAMELLIA_KEY_BITS camellia; /* all symmetric algorithms */
1219 TPMI_CAMELLIA_KEY_BITS camellia; /* all symmetric algorithms */
12181220 TPM2_KEY_BITS sym; /* when selector may be any of the symmetric block ciphers */
12191221 TPMI_ALG_HASH exclusiveOr; /* overload for using xor. NOTE TPM2_ALG_NULL is not allowed */
12201222 } TPMU_SYM_KEY_BITS;
111111 Esys_GetTime
112112 Esys_GetTime_Async
113113 Esys_GetTime_Finish
114 Esys_GetSysContext
114115 Esys_HMAC
115116 Esys_HMAC_Async
116117 Esys_HMAC_Finish
330331 Esys_StirRandom_Async
331332 Esys_StirRandom_Finish
332333 Esys_TRSess_GetAttributes
334 Esys_TRSess_GetAuthRequired
333335 Esys_TRSess_GetNonceTPM
334336 Esys_TRSess_SetAttributes
335337 Esys_TR_Close
340342 Esys_TR_GetName
341343 Esys_TR_Serialize
342344 Esys_TR_SetAuth
345 Esys_TR_GetTpmHandle;
343346 Esys_TestParms
344347 Esys_TestParms_Async
345348 Esys_TestParms_Finish
351354 Esys_VerifySignature_Finish
352355 Esys_ZGen_2Phase
353356 Esys_ZGen_2Phase_Async
354 Esys_ZGen_2Phase_Finish
357 Esys_ZGen_2Phase_Finish
109109 Esys_GetTime;
110110 Esys_GetTime_Async;
111111 Esys_GetTime_Finish;
112 Esys_GetSysContext;
112113 Esys_Hash;
113114 Esys_Hash_Async;
114115 Esys_Hash_Finish;
331332 Esys_TestParms_Finish;
332333 Esys_TRSess_GetAttributes;
333334 Esys_TRSess_SetAttributes;
335 Esys_TRSess_GetAuthRequired;
334336 Esys_TRSess_GetNonceTPM;
335337 Esys_TR_Close;
336338 Esys_TR_Deserialize;
340342 Esys_TR_GetName;
341343 Esys_TR_Serialize;
342344 Esys_TR_SetAuth;
345 Esys_TR_GetTpmHandle;
343346 Esys_Unseal;
344347 Esys_Unseal_Async;
345348 Esys_Unseal_Finish;
66 Description: TPM2 Enhanced System API library.
77 URL: https://github.com/tpm2-software/tpm2-tss
88 Version: @VERSION@
9 Requires.private: tss2-mu tss2-sys tss2-tcti-device tss2-tcti-mssim
9 Requires.private: tss2-mu tss2-sys
1010 Cflags: -I${includedir}
1111 Libs: -ltss2-esys -L${libdir}
1212 Libs.private: @LIBDL_LDFLAGS@ @LIBSOCKET_LDFLAGS@ @TSS2_ESYS_LDFLAGS_CRYPTO@
0 LIBRARY tss2-fapi
1 EXPORTS
2 Fapi_Initialize
3 Fapi_Initialize_Async
4 Fapi_Initialize_Finish
5 Fapi_Finalize
6 Fapi_Free
7 Fapi_GetTcti
8 Fapi_GetPollHandles
9 Fapi_GetInfo
10 Fapi_GetInfo_Async
11 Fapi_GetInfo_Finish
12 Fapi_Provision
13 Fapi_Provision_Async
14 Fapi_Provision_Finish
15 Fapi_GetPlatformCertificates
16 Fapi_GetPlatformCertificates_Async
17 Fapi_GetPlatformCertificates_Finish
18 Fapi_GetRandom
19 Fapi_GetRandom_Async
20 Fapi_GetRandom_Finish
21 Fapi_Import
22 Fapi_Import_Async
23 Fapi_Import_Finish
24 Fapi_List
25 Fapi_List_Async
26 Fapi_List_Finish
27 Fapi_Delete
28 Fapi_Delete_Async
29 Fapi_Delete_Finish
30 Fapi_ChangeAuth
31 Fapi_ChangeAuth_Async
32 Fapi_ChangeAuth_Finish
33 Fapi_SetDescription
34 Fapi_SetDescription_Async
35 Fapi_SetDescription_Finish
36 Fapi_GetDescription
37 Fapi_GetDescription_Async
38 Fapi_GetDescription_Finish
39 Fapi_SetAppData
40 Fapi_SetAppData_Async
41 Fapi_SetAppData_Finish
42 Fapi_GetAppData
43 Fapi_GetAppData_Async
44 Fapi_GetAppData_Finish
45 Fapi_GetTpmBlobs
46 Fapi_GetTpmBlobs_Async
47 Fapi_GetTpmBlobs_Finish
48 Fapi_CreateKey
49 Fapi_CreateKey_Async
50 Fapi_CreateKey_Finish
51 Fapi_Sign
52 Fapi_Sign_Async
53 Fapi_Sign_Finish
54 Fapi_VerifySignature
55 Fapi_VerifySignature_Async
56 Fapi_VerifySignature_Finish
57 Fapi_Encrypt
58 Fapi_Encrypt_Async
59 Fapi_Encrypt_Finish
60 Fapi_Decrypt
61 Fapi_Decrypt_Async
62 Fapi_Decrypt_Finish
63 Fapi_SetCertificate
64 Fapi_SetCertificate_Async
65 Fapi_SetCertificate_Finish
66 Fapi_GetCertificate
67 Fapi_GetCertificate_Async
68 Fapi_GetCertificate_Finish
69 Fapi_ExportKey
70 Fapi_ExportKey_Async
71 Fapi_ExportKey_Finish
72 Fapi_CreateSeal
73 Fapi_CreateSeal_Async
74 Fapi_CreateSeal_Finish
75 Fapi_Unseal
76 Fapi_Unseal_Async
77 Fapi_Unseal_Finish
78 Fapi_ExportPolicy
79 Fapi_ExportPolicy_Async
80 Fapi_ExportPolicy_Finish
81 Fapi_AuthorizePolicy
82 Fapi_AuthorizePolicy_Async
83 Fapi_AuthorizePolicy_Finish
84 Fapi_WriteAuthorizeNv
85 Fapi_WriteAuthorizeNv_Async
86 Fapi_WriteAuthorizeNv_Finish
87 Fapi_PcrRead
88 Fapi_PcrRead_Async
89 Fapi_PcrRead_Finish
90 Fapi_PcrExtend
91 Fapi_PcrExtend_Async
92 Fapi_PcrExtend_Finish
93 Fapi_Quote
94 Fapi_Quote_Async
95 Fapi_Quote_Finish
96 Fapi_VerifyQuote
97 Fapi_VerifyQuote_Async
98 Fapi_VerifyQuote_Finish
99 Fapi_CreateNv
100 Fapi_CreateNv_Async
101 Fapi_CreateNv_Finish
102 Fapi_NvRead
103 Fapi_NvRead_Async
104 Fapi_NvRead_Finish
105 Fapi_NvWrite
106 Fapi_NvWrite_Async
107 Fapi_NvWrite_Finish
108 Fapi_NvExtend
109 Fapi_NvExtend_Async
110 Fapi_NvExtend_Finish
111 Fapi_NvIncrement
112 Fapi_NvIncrement_Async
113 Fapi_NvIncrement_Finish
114 Fapi_NvSetBits
115 Fapi_NvSetBits_Async
116 Fapi_NvSetBits_Finish
117 Fapi_SetAuthCB
118 Fapi_SetBranchCB
119 Fapi_SetSignCB
120 Fapi_SetPolicyActionCB
0 {
1 global:
2 Fapi_Initialize;
3 Fapi_Initialize_Async;
4 Fapi_Initialize_Finish;
5 Fapi_Finalize;
6 Fapi_Free;
7 Fapi_GetTcti;
8 Fapi_GetPollHandles;
9 Fapi_GetInfo;
10 Fapi_GetInfo_Async;
11 Fapi_GetInfo_Finish;
12 Fapi_Provision;
13 Fapi_Provision_Async;
14 Fapi_Provision_Finish;
15 Fapi_GetPlatformCertificates;
16 Fapi_GetPlatformCertificates_Async;
17 Fapi_GetPlatformCertificates_Finish;
18 Fapi_GetRandom;
19 Fapi_GetRandom_Async;
20 Fapi_GetRandom_Finish;
21 Fapi_Import;
22 Fapi_Import_Async;
23 Fapi_Import_Finish;
24 Fapi_List;
25 Fapi_List_Async;
26 Fapi_List_Finish;
27 Fapi_Delete;
28 Fapi_Delete_Async;
29 Fapi_Delete_Finish;
30 Fapi_ChangeAuth;
31 Fapi_ChangeAuth_Async;
32 Fapi_ChangeAuth_Finish;
33 Fapi_SetDescription;
34 Fapi_SetDescription_Async;
35 Fapi_SetDescription_Finish;
36 Fapi_GetDescription;
37 Fapi_GetDescription_Async;
38 Fapi_GetDescription_Finish;
39 Fapi_SetAppData;
40 Fapi_SetAppData_Async;
41 Fapi_SetAppData_Finish;
42 Fapi_GetAppData;
43 Fapi_GetAppData_Async;
44 Fapi_GetAppData_Finish;
45 Fapi_GetTpmBlobs;
46 Fapi_GetTpmBlobs_Async;
47 Fapi_GetTpmBlobs_Finish;
48 Fapi_CreateKey;
49 Fapi_CreateKey_Async;
50 Fapi_CreateKey_Finish;
51 Fapi_Sign;
52 Fapi_Sign_Async;
53 Fapi_Sign_Finish;
54 Fapi_VerifySignature;
55 Fapi_VerifySignature_Async;
56 Fapi_VerifySignature_Finish;
57 Fapi_Encrypt;
58 Fapi_Encrypt_Async;
59 Fapi_Encrypt_Finish;
60 Fapi_Decrypt;
61 Fapi_Decrypt_Async;
62 Fapi_Decrypt_Finish;
63 Fapi_SetCertificate;
64 Fapi_SetCertificate_Async;
65 Fapi_SetCertificate_Finish;
66 Fapi_GetCertificate;
67 Fapi_GetCertificate_Async;
68 Fapi_GetCertificate_Finish;
69 Fapi_ExportKey;
70 Fapi_ExportKey_Async;
71 Fapi_ExportKey_Finish;
72 Fapi_CreateSeal;
73 Fapi_CreateSeal_Async;
74 Fapi_CreateSeal_Finish;
75 Fapi_Unseal;
76 Fapi_Unseal_Async;
77 Fapi_Unseal_Finish;
78 Fapi_ExportPolicy;
79 Fapi_ExportPolicy_Async;
80 Fapi_ExportPolicy_Finish;
81 Fapi_AuthorizePolicy;
82 Fapi_AuthorizePolicy_Async;
83 Fapi_AuthorizePolicy_Finish;
84 Fapi_WriteAuthorizeNv;
85 Fapi_WriteAuthorizeNv_Async;
86 Fapi_WriteAuthorizeNv_Finish;
87 Fapi_PcrRead;
88 Fapi_PcrRead_Async;
89 Fapi_PcrRead_Finish;
90 Fapi_PcrExtend;
91 Fapi_PcrExtend_Async;
92 Fapi_PcrExtend_Finish;
93 Fapi_Quote;
94 Fapi_Quote_Async;
95 Fapi_Quote_Finish;
96 Fapi_VerifyQuote;
97 Fapi_VerifyQuote_Async;
98 Fapi_VerifyQuote_Finish;
99 Fapi_CreateNv;
100 Fapi_CreateNv_Async;
101 Fapi_CreateNv_Finish;
102 Fapi_NvRead;
103 Fapi_NvRead_Async;
104 Fapi_NvRead_Finish;
105 Fapi_NvWrite;
106 Fapi_NvWrite_Async;
107 Fapi_NvWrite_Finish;
108 Fapi_NvExtend;
109 Fapi_NvExtend_Async;
110 Fapi_NvExtend_Finish;
111 Fapi_NvIncrement;
112 Fapi_NvIncrement_Async;
113 Fapi_NvIncrement_Finish;
114 Fapi_NvSetBits;
115 Fapi_NvSetBits_Async;
116 Fapi_NvSetBits_Finish;
117 Fapi_SetAuthCB;
118 Fapi_SetBranchCB;
119 Fapi_SetSignCB;
120 Fapi_SetPolicyActionCB;
121 local:
122 *;
123 };
0 prefix=@prefix@
1 exec_prefix=@exec_prefix@
2 libdir=@libdir@
3 includedir=@includedir@
4
5 Name: tss2-fapi
6 Description: TPM2 Feature API library.
7 URL: https://github.com/tpm2-software/tpm2-tss
8 Version: @VERSION@
9 Requires.private: tss2-mu tss2-esys tss2-tctildr libcurl libcrypto json-c
10 Cflags: -I${includedir}
11 Libs: -ltss2-fapi -L${libdir}
22 dnl is on PATH. If it is not we display an error message using AC_MSG_ERROR.
33 dnl $1: program name
44 AC_DEFUN([ERROR_IF_NO_PROG],[
5 AC_CHECK_PROG([result_$1], [$1], [yes], [no])
6 AS_IF([test "x$result_$1" != "xyes"], [
5 AC_CHECK_PROG(AS_TR_SH([result_$1]), [$1], [yes], [no])
6 AS_VAR_PUSHDEF([result], [result_$1])
7 AS_IF([test "x$result" != "xyes"], [
78 AC_MSG_ERROR([Missing required program '$1': ensure it is installed and on PATH.])
89 ])
10 AS_VAR_POPDEF([result])
911 ])
1212 This page is part of release @VERSION@ of Intel's implementation of the TCG
1313 TPM2 Software Stack (TSS2). A description of the project, information about
1414 reporting bugs, and the latest version of this page can be found at
15 \%https://github.com/01org/tpm2-tss/.
15 \%https://github.com/tpm2-software/tpm2-tss/.
0 #!/bin/bash
1
2 set -x
3
4 #set -euf
5
6 echo "Creating ekcert for $1 => $3"
7 echo "Creating ekcert for $2 => $4"
8
9 ROOTCRT=$6.crt
10 ROOTCRTPEM=$6.pem
11 INTERMEDCRT=$5.crt
12 ROOTCRL=$6.crl
13 INTERMEDCRL=$5.crl
14
15 EKCADIR="$(dirname $(realpath ${0}))/"
16
17 CA_DIR="$(mktemp -d ekca-XXXXXX)"
18
19 pushd "$CA_DIR"
20
21 mkdir root-ca
22 pushd root-ca
23
24 mkdir certreqs certs crl newcerts private
25 touch root-ca.index
26 echo 00 > root-ca.crlnum
27 echo 1000 > root-ca.serial
28 echo "123456" > pass.txt
29
30 cp "${EKCADIR}/root-ca.cnf" ./
31 export OPENSSL_CONF=./root-ca.cnf
32 ROOT_URL="file:$ROOTCRT"
33 sed -i "s|ROOTCRT|$ROOT_URL|g" $OPENSSL_CONF
34 ROOT_URL="file:$ROOTCRL"
35 sed -i "s|ROOTCRL|$ROOT_URL|g" $OPENSSL_CONF
36 openssl req -new -out root-ca.req.pem -passout file:pass.txt
37
38 #
39 # Create self signed root certificate
40 #
41 openssl ca -selfsign \
42 -in root-ca.req.pem \
43 -out root-ca.cert.pem \
44 -extensions root-ca_ext \
45 -startdate `date +%y%m%d000000Z -u -d -1day` \
46 -enddate `date +%y%m%d000000Z -u -d +10years+1day` \
47 -passin file:pass.txt -batch
48
49 openssl x509 -outform der -in root-ca.cert.pem -out root-ca.cert.crt
50
51 openssl verify -verbose -CAfile root-ca.cert.pem \
52 root-ca.cert.pem
53
54 openssl ca -gencrl -cert root-ca.cert.pem \
55 -out root-ca.cert.crl.pem -passin file:pass.txt
56 openssl crl -in root-ca.cert.crl.pem -outform DER -out root-ca.cert.crl
57
58 popd #root-ca
59
60 #
61 # Create intermediate certificate
62 #
63 mkdir intermed-ca
64 pushd intermed-ca
65
66 mkdir certreqs certs crl newcerts private
67 touch intermed-ca.index
68 echo 00 > intermed-ca.crlnum
69 echo 2000 > intermed-ca.serial
70 echo "abcdef" > pass.txt
71
72 cp "${EKCADIR}/intermed-ca.cnf" ./
73 export OPENSSL_CONF=./intermed-ca.cnf
74
75 # Adapt CRT URL to current test directory
76 sed -i "s|ROOTCRT|$ROOT_URL|g" $OPENSSL_CONF
77
78 openssl req -new -out intermed-ca.req.pem -passout file:pass.txt
79
80 openssl req -new \
81 -key private/intermed-ca.key.pem \
82 -out intermed-ca.req.pem \
83 -passin file:pass.txt
84
85 openssl rsa -inform PEM -in private/intermed-ca.key.pem \
86 -outform DER -out private/intermed-ca.key.der -passin file:pass.txt
87
88 cp intermed-ca.req.pem \
89 ../root-ca/certreqs/
90
91 INTERMED_URL="file:$INTERMEDCRT"
92 sed -i "s|INTERMEDCRT|$INTERMED_URL|g" $OPENSSL_CONF
93
94 pushd ../root-ca
95 export OPENSSL_CONF=./root-ca.cnf
96
97 openssl ca \
98 -in certreqs/intermed-ca.req.pem \
99 -out certs/intermed-ca.cert.pem \
100 -extensions intermed-ca_ext \
101 -startdate `date +%y%m%d000000Z -u -d -1day` \
102 -enddate `date +%y%m%d000000Z -u -d +5years+1day` \
103 -passin file:pass.txt -batch
104
105 openssl x509 -outform der -in certs/intermed-ca.cert.pem \
106 -out certs/intermed-ca.cert.crt
107
108 openssl verify -verbose -CAfile root-ca.cert.pem \
109 certs/intermed-ca.cert.pem
110
111 cp certs/intermed-ca.cert.pem \
112 ../intermed-ca
113
114 cp certs/intermed-ca.cert.crt \
115 ../intermed-ca
116
117 popd #root-ca
118
119 export OPENSSL_CONF=./intermed-ca.cnf
120 openssl ca -gencrl -cert ../root-ca/certs/intermed-ca.cert.pem \
121 -out intermed-ca.crl.pem -passin file:pass.txt
122 openssl crl -in intermed-ca.crl.pem -outform DER -out intermed-ca.crl
123
124 popd #intermed-ca
125
126 #
127 # Create RSA EK certificate
128 #
129 mkdir ek
130 pushd ek
131
132 cp "${EKCADIR}/ek.cnf" ./
133 export OPENSSL_CONF=ek.cnf
134 echo "abc123" > pass.txt
135
136 # Adapt CRT and CRL URL to current test directory
137
138 INTERMED_URL="file:$INTERMEDCRT"
139 sed -i "s|INTERMEDCRT|$INTERMED_URL|g" $OPENSSL_CONF
140
141 INTERMED_URL="file:$INTERMEDCRL"
142 sed -i "s|INTERMEDCRL|$INTERMED_URL|g" $OPENSSL_CONF
143
144 cp "$1" ../intermed-ca/certreqs/ek.pub.pem
145
146 openssl req -new -nodes -newkey rsa:2048 -passin file:pass.txt -out ../intermed-ca/certreqs/nonsense.csr.pem
147
148 pushd ../intermed-ca
149 export OPENSSL_CONF=./intermed-ca.cnf
150
151 openssl x509 -req -in certreqs/nonsense.csr.pem -force_pubkey certreqs/ek.pub.pem -out certs/ek.cert.der \
152 -outform DER -extfile ../ek/ek.cnf -extensions ek_ext -set_serial 12345 \
153 -CA intermed-ca.cert.pem -CAkey private/intermed-ca.key.pem -passin file:pass.txt
154
155 cp certs/ek.cert.der ../ek
156
157 popd #intermed-ca
158
159 popd #EK
160
161 #
162 # Create ECC EK Certificate
163 #
164 mkdir ekecc
165 pushd ekecc
166
167 cp "${EKCADIR}/ek.cnf" ./
168 export OPENSSL_CONF=ek.cnf
169 echo "abc123" > pass.txt
170
171 # Adapt CRT and CRL URL to current test directory
172
173 INTERMED_URL="file:$INTERMEDCRT"
174 sed -i "s|INTERMEDCRT|$INTERMED_URL|g" $OPENSSL_CONF
175
176 INTERMED_URL="file:$INTERMEDCRL"
177 sed -i "s|INTERMEDCRL|$INTERMED_URL|g" $OPENSSL_CONF
178
179 cp "$2" ../intermed-ca/certreqs/ekecc.pub.pem
180
181 openssl req -new -nodes -newkey rsa:2048 -passin file:pass.txt -out ../intermed-ca/certreqs/nonsense.csr.pem
182
183 pushd ../intermed-ca
184 export OPENSSL_CONF=./intermed-ca.cnf
185
186 openssl x509 -req -in certreqs/nonsense.csr.pem -force_pubkey certreqs/ekecc.pub.pem -out certs/ekecc.cert.der \
187 -outform DER -extfile ../ek/ek.cnf -extensions ek_ext -set_serial 12345 \
188 -CA intermed-ca.cert.pem -CAkey private/intermed-ca.key.pem -passin file:pass.txt
189
190 cp certs/ekecc.cert.der ../ekecc
191
192 popd #intermed-ca
193
194 popd #EK
195
196 popd #CA_DIR
197
198 # Copy used CRL and CRT files to test directory.
199
200 cp "${CA_DIR}/ek/ek.cert.der" "$3"
201 cp "${CA_DIR}/ekecc/ekecc.cert.der" "$4"
202 cp "${CA_DIR}/intermed-ca/intermed-ca.cert.crt" "$INTERMEDCRT"
203 cp "${CA_DIR}/intermed-ca/intermed-ca.crl" "$INTERMEDCRL"
204 cp "${CA_DIR}/root-ca/root-ca.cert.crt" "$ROOTCRT"
205 cp "${CA_DIR}/root-ca/root-ca.cert.crl" "$ROOTCRL"
206 cp "${CA_DIR}/root-ca/root-ca.cert.pem" "$ROOTCRTPEM"
207
208 rm -rf $CA_DIR
0 oid_section = tcg_oids
1
2 [ tcg_oids ]
3 tcg-sv-tpm20 = 2.23.133.1.2
4 tcg-at-tpmManufacturer = 2.23.133.2.1
5 tcg-at-tpmModel = 2.23.133.2.2
6 tcg-at-tpmVersion = 2.23.133.2.3
7 tcg-at-tpmSpecification = 2.23.133.2.16
8 tcg-at-tpmSecurityAssertions = 2.23.133.2.18
9 tcg-kp-EKCertificate = 2.23.133.8.1
10
11 [ req ]
12 prompt = no
13 distinguished_name = distinguished_name
14 subjectAltName = subject_alt_name
15
16 [ distinguished_name ]
17 commonName = this-tpm-sim
18 organizationName = tpm2-tss-testsuit
19
20 [ req_ext ]
21 subjectKeyIdentifier = hash
22
23 [ ek_ext ]
24 certificatePolicies = @polsect
25 subjectAltName = dirName:subAltName
26 basicConstraints = critical, CA:FALSE
27 subjectDirectoryAttributes = ASN1:SEQUENCE:subDirAttr
28 authorityKeyIdentifier = keyid:always
29 authorityInfoAccess = caIssuers;URI.0:INTERMEDCRT
30 crlDistributionPoints = URI.0:INTERMEDCRL
31 keyUsage = critical, keyEncipherment
32 #extendedKeyUsage = tcg-kp-EKCertificate
33 extendedKeyUsage = 2.23.133.8.1
34
35 [ polsect ]
36 policyIdentifier = anyPolicy
37 CPS.1="http://my.host.name/"
38
39 [ subAltName ]
40 #TPMManufacturer = 'TSS2'
41 .2.23.133.2.1 = id:54535332
42 .2.23.133.2.2 = tpmsimulator
43 .2.23.133.2.3 = id:00020008
44
45 #TODO: Remove
46 [ subAltName1 ]
47 C=DE
48 O=Testing
49 OU=whatever
50 commonName=abc
51
52 [ subDirAttr ]
53 tcg-at-tpmSpecification = SEQUENCE:tpmspec
54 #tcg-at-tpmSecurityAssertions = SEQUENCE:secassert
55
56 [ tpmspec ]
57 family = UTF8:2.0
58 level = INT:0
59 revision = INT:138
60
61 #[ secassert ]
62 #version = INT:0
63 #fieldUpgradable = BOOL:false
64 #...
0 #
1 # OpenSSL configuration for the Intermediate Certification Authority.
2 #
3
4 #
5 # This definition doesn't work if HOME isn't defined.
6 CA_HOME = .
7 RANDFILE = $ENV::CA_HOME/private/.rnd
8 oid_section = new_oids
9
10 #
11 # XMPP address Support
12 [ new_oids ]
13 xmppAddr = 1.3.6.1.5.5.7.8.5
14 dnsSRV = 1.3.6.1.5.5.7.8.7
15
16 #
17 # Default Certification Authority
18 [ ca ]
19 default_ca = intermed_ca
20
21 #
22 # Intermediate Certification Authority
23 [ intermed_ca ]
24 dir = $ENV::CA_HOME
25 certs = $dir/certs
26 serial = $dir/intermed-ca.serial
27 database = $dir/intermed-ca.index
28 new_certs_dir = $dir/newcerts
29 certificate = $dir/intermed-ca.cert.pem
30 private_key = $dir/private/intermed-ca.key.pem
31 default_days = 730 # Two years
32 crl = $dir/crl/intermed-ca.crl
33 crl_dir = $dir/crl
34 crlnumber = $dir/intermed-ca.crlnum
35 name_opt = multiline, align
36 cert_opt = no_pubkey
37 copy_extensions = copy
38 crl_extensions = crl_ext
39 default_crl_days = 30
40 default_md = sha256
41 preserve = no
42 email_in_dn = no
43 policy = policy
44 unique_subject = no
45
46 #
47 # Distinguished Name Policy
48 [ policy ]
49 countryName = optional
50 stateOrProvinceName = optional
51 localityName = optional
52 organizationName = optional
53 organizationalUnitName = optional
54 commonName = supplied
55
56 #
57 # Distinguished Name Policy for Personal Certificates
58 [ user_policy ]
59 countryName = supplied
60 stateOrProvinceName = optional
61 localityName = supplied
62 organizationName = optional
63 organizationalUnitName = optional
64 commonName = supplied
65 emailAddress = supplied
66 #xmppAddr = optional # Added to SubjAltName by req
67
68 #
69 # Intermediate CA request options
70 [ req ]
71 default_bits = 2048
72 default_keyfile = private/intermed-ca.key.pem
73 encrypt_key = yes
74 default_md = sha256
75 string_mask = utf8only
76 utf8 = yes
77 prompt = no
78 req_extensions = req_ext
79 distinguished_name = distinguished_name
80 subjectAltName = subject_alt_name
81
82 #
83 # Intermediate CA Request Extensions
84 [ req_ext ]
85 subjectKeyIdentifier = hash
86 subjectAltName = @subject_alt_name
87
88 #
89 # Distinguished Name (DN)
90 [ distinguished_name ]
91 organizationName = tpm2-software
92 commonName = intermed ek ca
93
94 #
95 # Server Certificate Extensions
96 [ server_ext ]
97 basicConstraints = CA:FALSE
98 keyUsage = critical, digitalSignature, keyEncipherment
99 extendedKeyUsage = critical, serverAuth, clientAuth
100 subjectKeyIdentifier = hash
101 authorityKeyIdentifier = keyid:always
102 issuerAltName = issuer:copy
103 authorityInfoAccess = @auth_info_access
104 crlDistributionPoints = crl_dist
105
106 #
107 # Client Certificate Extensions
108 [ client_ext ]
109 basicConstraints = CA:FALSE
110 keyUsage = critical, digitalSignature
111 extendedKeyUsage = critical, clientAuth
112 subjectKeyIdentifier = hash
113 authorityKeyIdentifier = keyid:always
114 issuerAltName = issuer:copy
115 authorityInfoAccess = @auth_info_access
116 crlDistributionPoints = crl_dist
117
118 #
119 # User Certificate Extensions
120 [ user_ext ]
121 basicConstraints = CA:FALSE
122 keyUsage = critical, digitalSignature
123 extendedKeyUsage = critical, clientAuth, emailProtection
124 subjectKeyIdentifier = hash
125 authorityKeyIdentifier = keyid:always
126 issuerAltName = issuer:copy
127 authorityInfoAccess = @auth_info_access
128 crlDistributionPoints = crl_dist
129
130 #
131 # CRL Certificate Extensions
132 [ crl_ext ]
133 authorityKeyIdentifier = keyid:always
134 issuerAltName = issuer:copy
135
136 #
137 # Certificate Authorities Alternative Names
138 [ subject_alt_name ]
139 URI = http://ca.example.net/
140 email = certmaster@example.net
141
142 #
143 # Certificate download addresses for the intermediate CA
144 [ auth_info_access ]
145 caIssuers;URI = INTERMEDCRT
146
147 #
148 # CRL Download address for the intermediate CA
149 [ crl_dist ]
150 fullname = INTERMEDCRL
151
152 # EOF
0 #
1 # OpenSSL configuration for the Root Certification Authority.
2 #
3
4 #
5 # This definition doesn't work if HOME isn't defined.
6 CA_HOME = .
7 RANDFILE = $ENV::CA_HOME/private/.rnd
8
9 #
10 # Default Certification Authority
11 [ ca ]
12 default_ca = root_ca
13
14 #
15 # Root Certification Authority
16 [ root_ca ]
17 dir = $ENV::CA_HOME
18 certs = $dir/certs
19 serial = $dir/root-ca.serial
20 database = $dir/root-ca.index
21 new_certs_dir = $dir/newcerts
22 certificate = $dir/root-ca.cert.pem
23 private_key = $dir/private/root-ca.key.pem
24 default_days = 1826 # Five years
25 crl = $dir/root-ca.crl
26 crl_dir = $dir/crl
27 crlnumber = $dir/root-ca.crlnum
28 name_opt = multiline, align
29 cert_opt = no_pubkey
30 copy_extensions = copy
31 crl_extensions = crl_ext
32 default_crl_days = 180
33 default_md = sha256
34 preserve = no
35 email_in_dn = no
36 policy = policy
37 unique_subject = no
38
39 #
40 # Distinguished Name Policy for CAs
41 [ policy ]
42 countryName = optional
43 stateOrProvinceName = optional
44 localityName = optional
45 organizationName = supplied
46 organizationalUnitName = optional
47 commonName = supplied
48
49 #
50 # Root CA Request Options
51 [ req ]
52 default_bits = 4096
53 default_keyfile = private/root-ca.key.pem
54 encrypt_key = yes
55 default_md = sha256
56 string_mask = utf8only
57 utf8 = yes
58 prompt = no
59 req_extensions = root-ca_req_ext
60 distinguished_name = distinguished_name
61 subjectAltName = @subject_alt_name
62
63 #
64 # Root CA Request Extensions
65 [ root-ca_req_ext ]
66 subjectKeyIdentifier = hash
67 subjectAltName = @subject_alt_name
68
69 #
70 # Distinguished Name (DN)
71 [ distinguished_name ]
72 organizationName = example.net
73 commonName = example.net Root Certification Authority
74
75 #
76 # Root CA Certificate Extensions
77 [ root-ca_ext ]
78 basicConstraints = critical, CA:true
79 keyUsage = critical, keyCertSign, cRLSign
80 nameConstraints = critical, @name_constraints
81 subjectKeyIdentifier = hash
82 subjectAltName = @subject_alt_name
83 authorityKeyIdentifier = keyid:always
84 issuerAltName = issuer:copy
85 authorityInfoAccess = @auth_info_access
86 crlDistributionPoints = crl_dist
87
88 #
89 # Intermediate CA Certificate Extensions
90 [ intermed-ca_ext ]
91 basicConstraints = critical, CA:true, pathlen:0
92 keyUsage = critical, keyCertSign, cRLSign
93 subjectKeyIdentifier = hash
94 subjectAltName = @subject_alt_name
95 authorityKeyIdentifier = keyid:always
96 issuerAltName = issuer:copy
97 authorityInfoAccess = @auth_info_access
98 crlDistributionPoints = crl_dist
99
100 #
101 # CRL Certificate Extensions
102 [ crl_ext ]
103 authorityKeyIdentifier = keyid:always
104 issuerAltName = issuer:copy
105
106 #
107 # Certificate Authorities Alternative Names
108 [ subject_alt_name ]
109 URI = http://ca.example.net/
110 email = certmaster@example.net
111
112 #
113 # Name Constraints
114 [ name_constraints ]
115 permitted;DNS.1 = example.net
116 permitted;DNS.2 = example.org
117 permitted;DNS.3 = lan
118 permitted;DNS.4 = onion
119 permitted;email.1 = example.net
120 permitted;email.2 = example.org
121
122 #
123 # Certificate download addresses for the root CA
124 [ auth_info_access ]
125 caIssuers;URI = ROOTCRT
126
127 #
128 # CRL Download address for the root CA
129 [ crl_dist ]
130 fullname = URI:ROOTCRL
8787 G_MESSAGES_DEBUG=all ./test/helper/tpm_transientempty
8888 if [ $? -ne 0 ]; then
8989 echo "TPM transient area not empty => skipping"
90 ret=77
90 ret=99
9191 break
9292 fi
9393
9696
9797 env TPM20TEST_TCTI_NAME="device" \
9898 TPM20TEST_DEVICE_FILE=${PTPM} \
99 TPM20TEST_TCTI="device:${PTPM}" \
99100 G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>$TPMSTATE_FILE1
100101 if [ $? -ne 0 ]; then
101102 echo "Error during dumpstate"
106107 echo "Execute the test script"
107108 env TPM20TEST_TCTI_NAME="device" \
108109 TPM20TEST_DEVICE_FILE=${PTPM} \
110 TPM20TEST_TCTI="device:${PTPM}" \
109111 G_MESSAGES_DEBUG=all $@
110112 ret=$?
111113 echo "Script returned $ret"
112114
113115 env TPM20TEST_TCTI_NAME="device" \
114116 TPM20TEST_DEVICE_FILE=${PTPM} \
117 TPM20TEST_TCTI="device:${PTPM}" \
115118 G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>$TPMSTATE_FILE2
116119 if [ $? -ne 0 ]; then
117120 echo "Error during dumpstate"
132135 break
133136 done
134137
135 # This sleep is sadly necessary: If we kill the tabrmd w/o sleeping for a
136 # second after the test finishes the simulator will die too. Bug in the
137 # simulator?
138 sleep 1
139 # teardown
140138 exit $ret
169169 return ${ret}
170170 }
171171
172 sanity_test
172 OS=$(uname)
173
174 if [ "$OS" == "Linux" ]; then
175 sanity_test
176 fi
173177
174178 # Once option processing is done, $@ should be the name of the test executable
175179 # followed by all of the options passed to the test executable.
180184 # start an instance of the simulator for the test, have it use a random port
181185 SIM_LOG_FILE=${TEST_BIN}_simulator.log
182186 SIM_PID_FILE=${TEST_BIN}_simulator.pid
183 SIM_TMP_DIR=$(mktemp --directory --tmpdir=/tmp tpm_server_XXXXXX)
187 SIM_TMP_DIR=$(mktemp -d /tmp/tpm_server_XXXXXX)
184188 PORT_MIN=1024
185189 PORT_MAX=65534
186190 BACKOFF_FACTOR=2
187191 BACKOFF_MAX=6
188192 BACKOFF=1
193
194 sock_tool="unknown"
195
196 if [ "$OS" == "Linux" ]; then
197 sock_tool="ss -lntp4"
198 elif [ "$OS" == "FreeBSD" ]; then
199 sock_tool="sockstat -l4"
200 fi
201
189202 for i in $(seq ${BACKOFF_MAX}); do
190203 SIM_PORT_DATA=$(od -A n -N 2 -t u2 /dev/urandom | awk -v min=${PORT_MIN} -v max=${PORT_MAX} '{print ($1 % (max - min)) + min}')
191204 if [ $(expr ${SIM_PORT_DATA} % 2) -eq 1 ]; then
201214 fi
202215 PID=$(cat ${SIM_PID_FILE})
203216 echo "simulator PID: ${PID}";
204 ss -lt4pn 2> /dev/null | grep "${PID}" | grep -q "${SIM_PORT_DATA}"
217 ${sock_tool} 2> /dev/null | grep "${PID}" | grep "${SIM_PORT_DATA}"
205218 ret_data=$?
206 ss -lt4pn 2> /dev/null | grep "${PID}" | grep -q "${SIM_PORT_CMD}"
219 ${sock_tool} 2> /dev/null | grep "${PID}" | grep "${SIM_PORT_CMD}"
207220 ret_cmd=$?
208221 if [ \( $ret_data -eq 0 \) -a \( $ret_cmd -eq 0 \) ]; then
209222 echo "Simulator with PID ${PID} bound to port ${SIM_PORT_DATA} and " \
227240 env TPM20TEST_TCTI_NAME="socket" \
228241 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
229242 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
243 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
230244 G_MESSAGES_DEBUG=all ./test/helper/tpm_startup
231245 if [ $? -ne 0 ]; then
232246 echo "TPM_StartUp failed"
234248 break
235249 fi
236250
237 env TPM20TEST_TCTI_NAME="socket" \
238 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
239 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
251 EKPUB_FILE=${TEST_BIN}_ekpub.pem
252 EKCERT_FILE=${TEST_BIN}_ekcert.crt
253 EKCERT_PEM_FILE=${TEST_BIN}_ekcert.pem
254
255
256 env TPM20TEST_TCTI_NAME="socket" \
257 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
258 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
259 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
260 G_MESSAGES_DEBUG=all ./test/helper/tpm_getek>$EKPUB_FILE
261 if [ $? -ne 0 ]; then
262 echo "TPM_getek failed"
263 ret=99
264 break
265 fi
266
267 EKECCPUB_FILE=${TEST_BIN}_ekeccpub.pem
268 EKECCCERT_FILE=${TEST_BIN}_ekecccert.crt
269 EKECCCERT_PEM_FILE=${TEST_BIN}_ekecccert.pem
270
271 env TPM20TEST_TCTI_NAME="socket" \
272 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
273 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
274 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
275 G_MESSAGES_DEBUG=all ./test/helper/tpm_getek_ecc>$EKECCPUB_FILE
276 if [ $? -ne 0 ]; then
277 echo "TPM_getek_ecc failed"
278 ret=99
279 break
280 fi
281
282 INTERMEDCA_FILE=${TEST_BIN}_intermedecc-ca
283 ROOTCA_FILE=${TEST_BIN}_root-ca
284
285 if [ "$OS" == "Linux" ]; then
286 SCRIPTDIR="$(dirname $(realpath $0))/"
287 ${SCRIPTDIR}/ekca/create_ca.sh "${EKPUB_FILE}" "${EKECCPUB_FILE}" "${EKCERT_FILE}" \
288 "${EKECCCERT_FILE}" "${INTERMEDCA_FILE}" "${ROOTCA_FILE}" >${TEST_BIN}_ca.log 2>&1
289 if [ $? -ne 0 ]; then
290 echo "ek-cert ca failed"
291 ret=99
292 break
293 fi
294 fi
295
296 # Determine the fingerprint of the RSA EK public.
297 FINGERPRINT=$(openssl pkey -pubin -inform PEM -in $EKPUB_FILE -outform DER | sha256sum | cut -f 1 -d ' ')
298 export FAPI_TEST_FINGERPRINT=" { \"hashAlg\" : \"sha256\", \"digest\" : \"$FINGERPRINT\" }"
299 openssl x509 -inform DER -in $EKCERT_FILE -outform PEM -out $EKCERT_PEM_FILE
300 export FAPI_TEST_CERTIFICATE="file:${EKCERT_PEM_FILE}"
301
302 # Determine the fingerprint of the RSA EK public.
303 FINGERPRINT_ECC=$(openssl pkey -pubin -inform PEM -in $EKECCPUB_FILE -outform DER | sha256sum | cut -f 1 -d ' ')
304 export FAPI_TEST_FINGERPRINT_ECC=" { \"hashAlg\" : \"sha256\", \"digest\" : \"$FINGERPRINT_ECC\" }"
305 openssl x509 -inform DER -in $EKECCCERT_FILE -outform PEM -out $EKECCCERT_PEM_FILE
306 export FAPI_TEST_CERTIFICATE_ECC="file:${EKECCCERT_PEM_FILE}"
307
308 cat $EKCERT_FILE | \
309 env TPM20TEST_TCTI_NAME="socket" \
310 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
311 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
312 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
313 G_MESSAGES_DEBUG=all ./test/helper/tpm_writeekcert 1C00002
314 if [ $? -ne 0 ]; then
315 echo "TPM_writeekcert failed"
316 ret=99
317 break
318 fi
319
320 cat $EKECCCERT_FILE | \
321 env TPM20TEST_TCTI_NAME="socket" \
322 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
323 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
324 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
325 G_MESSAGES_DEBUG=all ./test/helper/tpm_writeekcert 1C0000A
326 if [ $? -ne 0 ]; then
327 echo "TPM_writeekcert failed"
328 ret=99
329 fi
330
331 env TPM20TEST_TCTI_NAME="socket" \
332 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
333 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
334 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
240335 G_MESSAGES_DEBUG=all ./test/helper/tpm_transientempty
241336 if [ $? -ne 0 ]; then
242337 echo "TPM transient area not empty => skipping"
243 ret=77
338 ret=99
244339 break
245340 fi
246341
250345 env TPM20TEST_TCTI_NAME="socket" \
251346 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
252347 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
348 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
253349 G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>$TPMSTATE_FILE1
254350 if [ $? -ne 0 ]; then
255351 echo "Error during dumpstate"
261357 env TPM20TEST_TCTI_NAME="socket" \
262358 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
263359 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
360 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
361 FAPI_TEST_ROOT_CERT=${ROOTCA_FILE}.pem \
264362 G_MESSAGES_DEBUG=all $@
265363 ret=$?
266364 echo "Script returned $ret"
269367 env TPM20TEST_TCTI_NAME="socket" \
270368 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
271369 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
370 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
272371 G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>$TPMSTATE_FILE2
273372 if [ $? -ne 0 ]; then
274373 echo "Error during dumpstate"
294393 env TPM20TEST_TCTI_NAME="socket" \
295394 TPM20TEST_SOCKET_ADDRESS="127.0.0.1" \
296395 TPM20TEST_SOCKET_PORT="${SIM_PORT_DATA}" \
396 TPM20TEST_TCTI="mssim:host=127.0.0.1,port=${SIM_PORT_DATA}" \
297397 G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>$TPMSTATE_FILE2
298398 if [ $? -ne 0 ]; then
299399 echo "Error during dumpstate"
321421 # teardown
322422 daemon_stop ${SIM_PID_FILE}
323423 rm -rf ${SIM_TMP_DIR} ${SIM_PID_FILE}
424
324425 exit $ret
0 #!/usr/bin/env python3
1 # -*- coding: utf-8 -*-
2 #
3 # tpm2-tss documentation build configuration file, created by
4 # sphinx-quickstart on Thu Aug 29 14:00:06 2019.
5 #
6 # This file is execfile()d with the current directory set to its
7 # containing dir.
8 #
9 # Note that not all possible configuration values are present in this
10 # autogenerated file.
11 #
12 # All configuration values have a default; values that are commented out
13 # serve to show the default.
14
15 import subprocess
16
17 # Create (unused) root file
18 index_rst = open('index.rst', 'w')
19 index_rst.write('.. toctree::\n :maxdepth: 2')
20 index_rst.close()
21
22 # Build doxygen documentation
23 subprocess.call(r"""
24 cd ..
25 version="master"
26 echo "Version: $version"
27 sed "s/@top_srcdir@/./g;
28 s/@top_builddir@/./g;
29 s/@PACKAGE_NAME@/tpm2-tss/g;
30 s/@VERSION@/$version/g" Doxyfile.in > Doxyfile
31 SRCDIR='.' PROJECT='tpm2-tss' VERSION='2.3.0-dev' PERL_PATH='/usr/bin/perl' HAVE_DOT='NO' GENERATE_MAN='YES' GENERATE_RTF='YES' GENERATE_XML='NO' GENERATE_HTMLHELP='NO' GENERATE_CHI='NO' GENERATE_HTML='YES' GENERATE_LATEX='NO' DOCDIR=doxygen-doc doxygen Doxyfile
32 cd sphinx
33 """, shell=True)
34
35 # If extensions (or modules to document with autodoc) are in another directory,
36 # add these directories to sys.path here. If the directory is relative to the
37 # documentation root, use os.path.abspath to make it absolute, like shown here.
38 #sys.path.insert(0, os.path.abspath('.'))
39
40 # -- General configuration ------------------------------------------------
41
42 # If your documentation needs a minimal Sphinx version, state it here.
43 #needs_sphinx = '1.0'
44
45 # Add any Sphinx extension module names here, as strings. They can be
46 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
47 # ones.
48 extensions = []
49
50 # Add any paths that contain templates here, relative to this directory.
51 templates_path = ['_templates']
52
53 # The suffix(es) of source filenames.
54 # You can specify multiple suffix as a list of string:
55 # source_suffix = ['.rst', '.md']
56 source_suffix = '.rst'
57
58 # The encoding of source files.
59 #source_encoding = 'utf-8-sig'
60
61 # The master toctree document.
62 master_doc = 'index'
63
64 # General information about the project.
65 project = 'tpm2-tss'
66 copyright = '2019, open source community'
67 author = 'open source community'
68
69 # The version info for the project you're documenting, acts as replacement for
70 # |version| and |release|, also used in various other places throughout the
71 # built documents.
72 #
73 # The short X.Y version.
74 version = ''
75 # The full version, including alpha/beta/rc tags.
76 release = ''
77
78 # The language for content autogenerated by Sphinx. Refer to documentation
79 # for a list of supported languages.
80 #
81 # This is also used if you do content translation via gettext catalogs.
82 # Usually you set "language" from the command line for these cases.
83 language = None
84
85 # There are two options for replacing |today|: either, you set today to some
86 # non-false value, then it is used:
87 #today = ''
88 # Else, today_fmt is used as the format for a strftime call.
89 #today_fmt = '%B %d, %Y'
90
91 # List of patterns, relative to source directory, that match files and
92 # directories to ignore when looking for source files.
93 exclude_patterns = ['_build']
94
95 # The reST default role (used for this markup: `text`) to use for all
96 # documents.
97 #default_role = None
98
99 # If true, '()' will be appended to :func: etc. cross-reference text.
100 #add_function_parentheses = True
101
102 # If true, the current module name will be prepended to all description
103 # unit titles (such as .. function::).
104 #add_module_names = True
105
106 # If true, sectionauthor and moduleauthor directives will be shown in the
107 # output. They are ignored by default.
108 #show_authors = False
109
110 # The name of the Pygments (syntax highlighting) style to use.
111 pygments_style = 'sphinx'
112
113 # A list of ignored prefixes for module index sorting.
114 #modindex_common_prefix = []
115
116 # If true, keep warnings as "system message" paragraphs in the built documents.
117 #keep_warnings = False
118
119 # If true, `todo` and `todoList` produce output, else they produce nothing.
120 todo_include_todos = False
121
122
123 # -- Options for HTML output ----------------------------------------------
124
125 # The theme to use for HTML and HTML Help pages. See the documentation for
126 # a list of builtin themes.
127 html_theme = 'alabaster'
128
129 # Theme options are theme-specific and customize the look and feel of a theme
130 # further. For a list of options available for each theme, see the
131 # documentation.
132 #html_theme_options = {}
133
134 # Add any paths that contain custom themes here, relative to this directory.
135 #html_theme_path = []
136
137 # The name for this set of Sphinx documents. If None, it defaults to
138 # "<project> v<release> documentation".
139 #html_title = None
140
141 # A shorter title for the navigation bar. Default is the same as html_title.
142 #html_short_title = None
143
144 # The name of an image file (relative to this directory) to place at the top
145 # of the sidebar.
146 #html_logo = None
147
148 # The name of an image file (relative to this directory) to use as a favicon of
149 # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
150 # pixels large.
151 #html_favicon = None
152
153 # Add any paths that contain custom static files (such as style sheets) here,
154 # relative to this directory. They are copied after the builtin static files,
155 # so a file named "default.css" will overwrite the builtin "default.css".
156 html_static_path = ['_static']
157
158 # Add any extra paths that contain custom files (such as robots.txt or
159 # .htaccess) here, relative to this directory. These files are copied
160 # directly to the root of the documentation.
161 html_extra_path = ['../doxygen-doc/html']
162
163 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
164 # using the given strftime format.
165 #html_last_updated_fmt = '%b %d, %Y'
166
167 # If true, SmartyPants will be used to convert quotes and dashes to
168 # typographically correct entities.
169 #html_use_smartypants = True
170
171 # Custom sidebar templates, maps document names to template names.
172 #html_sidebars = {}
173
174 # Additional templates that should be rendered to pages, maps page names to
175 # template names.
176 #html_additional_pages = {}
177
178 # If false, no module index is generated.
179 #html_domain_indices = True
180
181 # If false, no index is generated.
182 #html_use_index = True
183
184 # If true, the index is split into individual pages for each letter.
185 #html_split_index = False
186
187 # If true, links to the reST sources are added to the pages.
188 #html_show_sourcelink = True
189
190 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
191 #html_show_sphinx = True
192
193 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
194 #html_show_copyright = True
195
196 # If true, an OpenSearch description file will be output, and all pages will
197 # contain a <link> tag referring to it. The value of this option must be the
198 # base URL from which the finished HTML is served.
199 #html_use_opensearch = ''
200
201 # This is the file name suffix for HTML files (e.g. ".xhtml").
202 #html_file_suffix = None
203
204 # Language to be used for generating the HTML full-text search index.
205 # Sphinx supports the following languages:
206 # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
207 # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
208 #html_search_language = 'en'
209
210 # A dictionary with options for the search language support, empty by default.
211 # Now only 'ja' uses this config value
212 #html_search_options = {'type': 'default'}
213
214 # The name of a javascript file (relative to the configuration directory) that
215 # implements a search results scorer. If empty, the default will be used.
216 #html_search_scorer = 'scorer.js'
217
218 # Output file base name for HTML help builder.
219 htmlhelp_basename = 'tpm2-tssdoc'
220
221 # -- Options for LaTeX output ---------------------------------------------
222
223 latex_elements = {
224 # The paper size ('letterpaper' or 'a4paper').
225 #'papersize': 'letterpaper',
226
227 # The font size ('10pt', '11pt' or '12pt').
228 #'pointsize': '10pt',
229
230 # Additional stuff for the LaTeX preamble.
231 #'preamble': '',
232
233 # Latex figure (float) alignment
234 #'figure_align': 'htbp',
235 }
236
237 # Grouping the document tree into LaTeX files. List of tuples
238 # (source start file, target name, title,
239 # author, documentclass [howto, manual, or own class]).
240 latex_documents = [
241 (master_doc, 'tpm2-tss.tex', 'tpm2-tss Documentation',
242 'open source community', 'manual'),
243 ]
244
245 # The name of an image file (relative to this directory) to place at the top of
246 # the title page.
247 #latex_logo = None
248
249 # For "manual" documents, if this is true, then toplevel headings are parts,
250 # not chapters.
251 #latex_use_parts = False
252
253 # If true, show page references after internal links.
254 #latex_show_pagerefs = False
255
256 # If true, show URL addresses after external links.
257 #latex_show_urls = False
258
259 # Documents to append as an appendix to all manuals.
260 #latex_appendices = []
261
262 # If false, no module index is generated.
263 #latex_domain_indices = True
264
265
266 # -- Options for manual page output ---------------------------------------
267
268 # One entry per manual page. List of tuples
269 # (source start file, name, description, authors, manual section).
270 man_pages = [
271 (master_doc, 'tpm2-tss', 'tpm2-tss Documentation',
272 [author], 1)
273 ]
274
275 # If true, show URL addresses after external links.
276 #man_show_urls = False
277
278
279 # -- Options for Texinfo output -------------------------------------------
280
281 # Grouping the document tree into Texinfo files. List of tuples
282 # (source start file, target name, title, author,
283 # dir menu entry, description, category)
284 texinfo_documents = [
285 (master_doc, 'tpm2-tss', 'tpm2-tss Documentation',
286 author, 'tpm2-tss', 'One line description of project.',
287 'Miscellaneous'),
288 ]
289
290 # Documents to append as an appendix to all manuals.
291 #texinfo_appendices = []
292
293 # If false, no module index is generated.
294 #texinfo_domain_indices = True
295
296 # How to display URL addresses: 'footnote', 'no', or 'inline'.
297 #texinfo_show_urls = 'footnote'
298
299 # If true, do not generate a @detailmenu in the "Top" node's menu.
300 #texinfo_no_detailmenu = False
198198 return_state_if_error(r, _ESYS_STATE_INTERNALERROR,
199199 "Finish (Execute Async)");
200200
201 /* If the command authorization is LOCKOUT we need to
202 * recompute session value with an empty auth */
203 if (authHandle == ESYS_TR_RH_LOCKOUT)
204 iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
205
201206 esysContext->state = _ESYS_STATE_SENT;
202207
203208 return r;
320320 goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
321321 }
322322
323 /* Update the meta data of the ESYS_TR object */
324 objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
325 size_t offset = 0;
326 r = Tss2_MU_TPMT_PUBLIC_Unmarshal(&esysContext->in.CreateLoaded.inPublic->buffer[0],
327 sizeof(TPMT_PUBLIC), &offset ,
328 &objectHandleNode->rsrc.misc.rsrc_key_pub.publicArea);
329 goto_if_error(r, "Unmarshal TPMT_PUBULIC", error_cleanup);
330
331323 /*Receive the TPM response and handle resubmissions if necessary. */
332324 r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
333325 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
389381 error_cleanup);
390382
391383
384 /* Update the meta data of the ESYS_TR object */
385 objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
386 objectHandleNode->rsrc.misc.rsrc_key_pub = *loutPublic;
387
392388 /* Check name and outPublic for consistency */
393 if (!iesys_compare_name(loutPublic, &name))
389 if (!iesys_compare_name(&objectHandleNode->rsrc.misc.rsrc_key_pub, &name))
394390 goto_error(r, TSS2_ESYS_RC_MALFORMED_RESPONSE,
395391 "in Public name not equal name in response", error_cleanup);
396392
481481
482482 sessionHandleNode->rsrc.misc.rsrc_session.sessionKey.size = authHash_size;
483483 LOGBLOB_DEBUG(&sessionHandleNode->rsrc.misc.rsrc_session.sessionKey
484 .buffer[0],
485 sessionHandleNode->rsrc.misc.rsrc_session.sessionKey.size,
486 "Session Key");
484 .buffer[0], authHash_size, "Session Key");
487485 return_if_error(r,"Error KDFa");
488
489 sessionHandleNode->rsrc.misc.rsrc_session.sessionKey.size = authHash_size;
490486 }
491487 size_t offset = 0;
492488 r = Tss2_MU_TPM2_HANDLE_Marshal(sessionHandleNode->rsrc.handle,
218218 esys_context->timeout = timeout;
219219 return TSS2_RC_SUCCESS;
220220 }
221
222 /** Helper function that returns sys contest from the give esys context.
223 *
224 * Function returns sys contest from the give esys context.
225 * @param esys_context [in] ESYS context.
226 * @param sys_context [out] SYS context.
227 * @retval TSS2_RC_SUCCESS on Success.
228 * @retval TSS2_ESYS_RC_BAD_REFERENCE if esys_context of sys_context are NULL.
229 */
230 TSS2_RC
231 Esys_GetSysContext(ESYS_CONTEXT *esys_context, TSS2_SYS_CONTEXT **sys_context)
232 {
233 if (esys_context == NULL || sys_context == NULL)
234 return TSS2_ESYS_RC_BAD_REFERENCE;
235
236 *sys_context = esys_context->sys;
237
238 return TSS2_RC_SUCCESS;
239 }
908908 int algo, mode, len;
909909 size_t key_len = 0;
910910 gcry_error_t err;
911 TSS2_RC r = TSS2_RC_SUCCESS;
912
911913 switch (tpm_sym_alg) {
912914 case TPM2_ALG_AES:
913915 switch (key_bits) {
950952 err = gcry_cipher_setiv(*cipher_hd, &iv[0], iv_len);
951953 if (err != GPG_ERR_NO_ERROR) {
952954 LOG_ERROR("Function gcry_cipher_setiv");
953 return TSS2_ESYS_RC_GENERAL_FAILURE;
955 gcry_cipher_close(*cipher_hd);
956 r = TSS2_ESYS_RC_GENERAL_FAILURE;
954957 }
955958 }
956 err = gcry_cipher_setkey(*cipher_hd, key, key_len);
957 if (err != GPG_ERR_NO_ERROR) {
958 LOG_ERROR("Function gcry_cipher_setkey");
959 return TSS2_ESYS_RC_GENERAL_FAILURE;
960 }
961 return TSS2_RC_SUCCESS;
959 if (r == TSS2_RC_SUCCESS) {
960 err = gcry_cipher_setkey(*cipher_hd, key, key_len);
961 if (err != GPG_ERR_NO_ERROR) {
962 LOG_ERROR("Function gcry_cipher_setkey");
963 gcry_cipher_close(*cipher_hd);
964 r = TSS2_ESYS_RC_GENERAL_FAILURE;
965 }
966 }
967 return r;
962968 }
963969
964970 /** Encrypt data with AES.
10041010 LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES output");
10051011 if (err != GPG_ERR_NO_ERROR) {
10061012 LOG_ERROR("Function gcry_cipher_encrypt");
1007 return TSS2_ESYS_RC_GENERAL_FAILURE;
1013 r = TSS2_ESYS_RC_GENERAL_FAILURE;
10081014 }
10091015 gcry_cipher_close(cipher_hd);
1010 return TSS2_RC_SUCCESS;
1016 return r;
10111017 }
10121018
10131019 /** Decrypt data with AES.
10561062 err = gcry_cipher_decrypt(cipher_hd, buffer, buffer_size, NULL, 0);
10571063 if (err != GPG_ERR_NO_ERROR) {
10581064 LOG_ERROR("Function gcry_cipher_decrypt");
1059 return TSS2_ESYS_RC_GENERAL_FAILURE;
1065 r = TSS2_ESYS_RC_GENERAL_FAILURE;
10601066 }
10611067 gcry_cipher_close(cipher_hd);
1062 return TSS2_RC_SUCCESS;
1068 return r;
10631069 }
10641070
10651071 /** Initialize gcrypt crypto backend.
803803 break;
804804 case TPM2_ECC_NIST_P224:
805805 curveId = NID_secp224r1;
806 key_size = 38;
806 key_size = 28;
807807 break;
808808 case TPM2_ECC_NIST_P256:
809809 curveId = NID_X9_62_prime256v1;
1414 if (__ptr != NULL) {
1515 free(__ptr);
1616 }
17 }
17 }
3535 }
3636
3737 /**
38 * Compare variables of type BYTE.
39 * @param[in] in1 Variable to be compared with:
40 * @param[in] in2
41 */
42 static bool
43 cmp_BYTE(const BYTE * in1, const BYTE * in2)
44 {
45 LOG_TRACE("call");
46 if (*in1 == *in2)
47 return true;
48 else {
49 LOG_TRACE("cmp false");
50 return false;
51 }
52 }
53
54 /**
5538 * Compare two arrays of type BYTE.
5639 * @param[in] in1 array to be compared with:.
5740 * @param[in] in2
6447 LOG_TRACE("cmp false");
6548 return false;
6649 }
67 for (size_t i = 0; i < count1; i++) {
68 if (!cmp_BYTE(&in1[i], &in2[i])) {
69 LOG_TRACE("cmp false");
70 return false;
71 }
72 }
50
51 if (memcmp(in1, in2, count2) != 0) {
52 LOG_TRACE("cmp false");
53 return false;
54 }
55
7356 return true;
7457 }
7558
167150 next_node_rsrc = node_rsrc->next;
168151 SAFE_FREE(node_rsrc);
169152 }
153 esys_context->rsrc_list = NULL;
170154 }
171155 /** Compute the TPM nonce of the session used for parameter encryption.
172156 *
12441228 * the command authorization are computed.
12451229 * @param[in] esys_context The esys context to issue the command on.
12461230 * @param[in] h1-3 The esys session resource objects.
1247 * @param[out] The list if the authorizations with teh computed HMACs.
1231 * @param[out] The list if the authorizations with the computed HMACs.
12481232 * @param[out] auth The computed HMAC value.
12491233 * @retval TSS2_RC_SUCCESS on success.
12501234 * @retval TSS2_ESYS_RC_MEMORY Memory can not be allocated.
14451429 r = Tss2_MU_TPMS_NV_PUBLIC_Marshal(&publicInfo->nvPublic,
14461430 &buffer[0], sizeof(TPMS_NV_PUBLIC),
14471431 &offset);
1448 return_if_error(r, "Marshaling TPMS_NV_PUBLIC");
1432 goto_if_error(r, "Marshaling TPMS_NV_PUBLIC", error_cleanup);
14491433
14501434 r = iesys_crypto_hash_update(cryptoContext, &buffer[0], offset);
1451 return_if_error(r, "crypto hash update");
1435 goto_if_error(r, "crypto hash update", error_cleanup);
14521436
14531437 r = iesys_crypto_hash_finish(&cryptoContext, &name->name[len_alg_id],
14541438 &size);
1455 return_if_error(r, "crypto hash finish");
1439 goto_if_error(r, "crypto hash finish", error_cleanup);
14561440
14571441 offset = 0;
14581442 r = Tss2_MU_TPMI_ALG_HASH_Marshal(publicInfo->nvPublic.nameAlg,
14591443 &name->name[0], sizeof(TPMI_ALG_HASH),
14601444 &offset);
1461 return_if_error(r, "Marshaling TPMI_ALG_HASH");
1445 goto_if_error(r, "Marshaling TPMI_ALG_HASH", error_cleanup);
14621446
14631447 name->size = size + len_alg_id;
14641448 return TSS2_RC_SUCCESS;
1449
1450 error_cleanup:
1451 if (cryptoContext)
1452 iesys_crypto_hash_abort(&cryptoContext);
1453 return r;
14651454 }
14661455
14671456 /** Compute the name of a TPM transient or persistent object.
14931482
14941483 r = Tss2_MU_TPMT_PUBLIC_Marshal(&publicInfo->publicArea,
14951484 &buffer[0], sizeof(TPMT_PUBLIC), &offset);
1496 return_if_error(r, "Marshaling TPMT_PUBLIC");
1485 goto_if_error(r, "Marshaling TPMT_PUBLIC", error_cleanup);
14971486
14981487 r = iesys_crypto_hash_update(cryptoContext, &buffer[0], offset);
1499 return_if_error(r, "crypto hash update");
1488 goto_if_error(r, "crypto hash update", error_cleanup);
15001489
15011490 r = iesys_crypto_hash_finish(&cryptoContext, &name->name[len_alg_id],
15021491 &size);
1503 return_if_error(r, "crypto hash finish");
1492 goto_if_error(r, "crypto hash finish", error_cleanup);
15041493
15051494 offset = 0;
15061495 r = Tss2_MU_TPMI_ALG_HASH_Marshal(publicInfo->publicArea.nameAlg,
15071496 &name->name[0], sizeof(TPMI_ALG_HASH),
15081497 &offset);
1509 return_if_error(r, "Marshaling TPMI_ALG_HASH");
1498 goto_if_error(r, "Marshaling TPMI_ALG_HASH", error_cleanup);
15101499
15111500 name->size = size + len_alg_id;
15121501 return TSS2_RC_SUCCESS;
1502
1503 error_cleanup:
1504 if (cryptoContext)
1505 iesys_crypto_hash_abort(&cryptoContext);
1506 return r;
15131507 }
15141508
15151509 /** Check whether the return code corresponds to an TPM error.
557557 SAFE_FREE(*nonceTPM);
558558 return r;
559559 }
560
561 /** Retrieves the associated TPM2_HANDLE from an ESYS_TR object.
562 *
563 * Retrieves the TPM2_HANDLE for an associated ESYS_TR object for use with the
564 * SAPI API or comparisons against raw TPM2_HANDLES from commands like
565 * TPM2_GetCapability or use of various handle bitwise comparisons. For example
566 * the mask TPM2_HR_NV_INDEX.
567 *
568 * @param esys_context [in,out] The ESYS_CONTEXT.
569 * @param esys_handle [in] The ESYS_TR object to retrieve the TPM2_HANDLE from.
570 * @param tpm_handle [out] The TPM2_HANDLE retrieved from the ESYS_TR object.
571 * @retval TSS2_RC_SUCCESS on Success.
572 * @retval TSS2_ESYS_RC_BAD_TR if the ESYS_TR object is unknown to the
573 * ESYS_CONTEXT or is ESYS_TR_NONE.
574 * @retval TSS2_ESYS_RC_BAD_VALUE if an unknown handle < ESYS_TR_MIN_OBJECT is
575 * passed.
576 * @retval TSS2_ESYS_RC_BAD_REFERENCE For invalid ESYS_CONTEXT.
577 */
578 TSS2_RC
579 Esys_TR_GetTpmHandle(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
580 TPM2_HANDLE * tpm_handle)
581 {
582 TSS2_RC r = TSS2_RC_SUCCESS;
583 RSRC_NODE_T *esys_object;
584
585 _ESYS_ASSERT_NON_NULL(esys_context);
586 _ESYS_ASSERT_NON_NULL(tpm_handle);
587
588 if (esys_handle == ESYS_TR_NONE) {
589 return TSS2_ESYS_RC_BAD_TR;
590 }
591
592 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
593 return_if_error(r, "Get resource object");
594
595 *tpm_handle = esys_object->rsrc.handle;
596
597 return TSS2_RC_SUCCESS;
598 };
599
600 /** Retrieve whether auth value is required from a Esys_TR session object.
601 *
602 * This function can be used to determin whether PoliyPassword or
603 * PlolicyAuthValue are used for a session.
604 * @param esys_context [in,out] The ESYS_CONTEXT.
605 * @param esys_handle [in,out] The ESYS_TRsess for which to retrieve the nonce.
606 * @param neeed [out] The boolean indicating whether auth value will be
607 * needed.
608 * @retval TSS2_RC_SUCCESS on Success.
609 * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library.
610 * @retval TSS2_ESYS_RC_BAD_REFERENCE if the esysContext is NULL.
611 * @retval TSS2_SYS_RC_* for SAPI errors.
612 */
613 TSS2_RC
614 Esys_TRSess_GetAuthRequired(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle,
615 TPMI_YES_NO *auth_needed)
616 {
617 RSRC_NODE_T *esys_object;
618 TSS2_RC r;
619 _ESYS_ASSERT_NON_NULL(esys_context);
620
621 r = esys_GetResourceObject(esys_context, esys_handle, &esys_object);
622 return_if_error(r, "Object not found");
623
624 if (esys_object->rsrc.rsrcType != IESYSC_SESSION_RSRC) {
625 return_if_error(TSS2_ESYS_RC_BAD_TR,
626 "Auth value needed for non-session object requested.");
627 }
628
629 if (esys_object->rsrc.misc.rsrc_session.type_policy_session == POLICY_AUTH ||
630 esys_object->rsrc.misc.rsrc_session.type_policy_session == POLICY_PASSWORD)
631 *auth_needed = TPM2_YES;
632 else
633 *auth_needed = TPM2_NO;
634 return TSS2_RC_SUCCESS;
635
636 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include "tss2_fapi.h"
11 #include "fapi_int.h"
12 #include "fapi_util.h"
13 #include "tss2_esys.h"
14 #include "fapi_policy.h"
15 #include "fapi_crypto.h"
16 #define LOGMODULE fapi
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20 /** One-Call function for Fapi_AuthorizePolicy
21 *
22 * If a current policy happens to be a PolicyAuthorize, then for it to be used,
23 * the user must first satisfy a policy authorized by a having been signed (and
24 * made into a ticket) by an authorized party.
25 *
26 * @param[in,out] context The FAPI context
27 * @param[in] policyPath The path to the policy file
28 * @param[in] keyPath The path to the signing key
29 * @param[in] policyRef A byte buffer that is included in the signature. May be
30 * NULL
31 * @param[in] policyRefSize The size of policyRef. Must be 0 if policyRef is
32 * NULL
33 *
34 * @retval TSS2_RC_SUCCESS: if the function call was a success.
35 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, policyPath or keyPath
36 * is NULL.
37 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
38 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath or keyPath does not
39 * map to a FAPI policy or key object.
40 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
41 * operation already pending.
42 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
43 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
44 * internal operations or return parameters.
45 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
46 * config file.
47 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
48 * the function.
49 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
50 * this function needs to be called again.
51 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
52 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
53 * during authorization.
54 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
55 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
56 * is not set.
57 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
58 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
59 * was not successful.
60 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
61 */
62 TSS2_RC
63 Fapi_AuthorizePolicy(
64 FAPI_CONTEXT *context,
65 char const *policyPath,
66 char const *keyPath,
67 uint8_t const *policyRef,
68 size_t policyRefSize)
69 {
70 TSS2_RC r, r2;
71
72 LOG_TRACE("called for context:%p", context);
73
74 /* Check for NULL parameters */
75 check_not_null(context);
76 check_not_null(policyPath);
77 check_not_null(keyPath);
78
79 /* Check whether TCTI and ESYS are initialized */
80 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
81 TSS2_FAPI_RC_NO_TPM);
82
83 /* If the async state automata of FAPI shall be tested, then we must not set
84 the timeouts of ESYS to blocking mode.
85 During testing, the mssim tcti will ensure multiple re-invocations.
86 Usually however the synchronous invocations of FAPI shall instruct ESYS
87 to block until a result is available. */
88 #ifndef TEST_FAPI_ASYNC
89 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
90 return_if_error_reset_state(r, "Set Timeout to blocking");
91 #endif /* TEST_FAPI_ASYNC */
92
93 r = Fapi_AuthorizePolicy_Async(context, policyPath, keyPath,
94 policyRef, policyRefSize);
95 return_if_error_reset_state(r, "Policy_AuthorizeNewpolicy");
96
97 do {
98 /* We wait for file I/O to be ready if the FAPI state automata
99 are in a file I/O state. */
100 r = ifapi_io_poll(&context->io);
101 return_if_error(r, "Something went wrong with IO polling");
102
103 /* Repeatedly call the finish function, until FAPI has transitioned
104 through all execution stages / states of this invocation. */
105 r = Fapi_AuthorizePolicy_Finish(context);
106 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
107
108 /* Reset the ESYS timeout to non-blocking, immediate response. */
109 r2 = Esys_SetTimeout(context->esys, 0);
110 return_if_error(r2, "Set Timeout to non-blocking");
111
112 return_if_error_reset_state(r, "PolicyAuthorizeNewPolicy");
113
114 return TSS2_RC_SUCCESS;
115 }
116
117 /** Asynchronous function for Fapi_AuthorizePolicy
118 *
119 * If a current policy happens to be a PolicyAuthorize, then for it to be used,
120 * the user must first satisfy a policy authorized by a having been signed (and
121 * made into a ticket) by an authorized party.
122 *
123 * Call Fapi_AuthorizePolicy_Finish to finish the execution of this command.
124 *
125 * @param[in,out] context The FAPI context
126 * @param[in] policyPath The path to the policy file
127 * @param[in] keyPath The path to the signing key
128 * @param[in] policyRef A byte buffer that is included in the signature. May be
129 * NULL
130 * @param[in] policyRefSize The size of policyRef. Must be 0 if policyRef is
131 * NULL
132 *
133 * @retval TSS2_RC_SUCCESS: if the function call was a success.
134 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, policyPath or keyPath
135 * is NULL.
136 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
137 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath or keyPath does not
138 * map to a FAPI policy or key object.
139 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
140 * operation already pending.
141 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
142 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
143 * internal operations or return parameters.
144 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
145 * the function.
146 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
147 * config file.
148 */
149 TSS2_RC
150 Fapi_AuthorizePolicy_Async(
151 FAPI_CONTEXT *context,
152 char const *policyPath,
153 char const *keyPath,
154 uint8_t const *policyRef,
155 size_t policyRefSize)
156 {
157 LOG_TRACE("called for context:%p", context);
158 LOG_TRACE("policyPath: %s", policyPath);
159 LOG_TRACE("keyPath: %s", keyPath);
160 if (policyRef) {
161 LOGBLOB_TRACE(policyRef, policyRefSize, "policyRef");
162 } else {
163 LOG_TRACE("policyRef: (null) policyRefSize: %zi", policyRefSize);
164 }
165
166 TSS2_RC r;
167 IFAPI_Fapi_AuthorizePolicy *policy;
168
169 /* Check for NULL parameters */
170 check_not_null(context);
171 check_not_null(policyPath);
172 check_not_null(keyPath);
173
174 /* Reset all context-internal session state information. */
175 r = ifapi_session_init(context);
176 return_if_error(r, "Initialize AuthorizePolicy");
177
178 /* Copy parameters to context for use during _Finish. */
179 policy = &context->cmd.Policy_AuthorizeNewPolicy;
180 strdup_check(policy->policyPath, policyPath, r, error_cleanup);
181 strdup_check(policy->signingKeyPath, keyPath, r, error_cleanup);
182 if (policyRef) {
183 FAPI_COPY_DIGEST(&policy->policyRef.buffer[0],
184 policy->policyRef.size, policyRef, policyRefSize);
185 } else {
186 policy->policyRef.size = 0;
187 }
188
189 /* Initialize the context state for this operation. */
190 context->state = AUTHORIZE_NEW_LOAD_KEY;
191
192 LOG_TRACE("finished");
193 return TSS2_RC_SUCCESS;
194
195 error_cleanup:
196 /* Cleanup duplicated input parameters that were copied before. */
197 SAFE_FREE(policy->policyPath);
198 SAFE_FREE(policy->signingKeyPath);
199 return r;
200 }
201
202 /** Asynchronous finish function for Fapi_AuthorizePolicy
203 *
204 * This function should be called after a previous Fapi_AuthorizePolicy_Async.
205 *
206 * @param[in,out] context The FAPI_CONTEXT
207 *
208 * @retval TSS2_RC_SUCCESS: if the function call was a success.
209 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
210 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
211 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
212 * operation already pending.
213 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
214 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
215 * internal operations or return parameters.
216 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
217 * complete. Call this function again later.
218 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
219 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
220 * during authorization.
221 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
222 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
223 * the function.
224 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
225 * is not set.
226 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
227 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
228 * was not successful.
229 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
230 */
231 TSS2_RC
232 Fapi_AuthorizePolicy_Finish(
233 FAPI_CONTEXT *context)
234 {
235 LOG_TRACE("called for context:%p", context);
236
237 TSS2_RC r;
238 TPMI_ALG_HASH hashAlg;
239 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
240 size_t hashSize;
241 size_t digestIdx;
242 TPM2B_DIGEST aHash;
243 char *publicKey = NULL;
244
245 /* Check for NULL parameters */
246 check_not_null(context);
247
248 /* Helpful alias pointers */
249 IFAPI_Fapi_AuthorizePolicy * command =
250 &context->cmd.Policy_AuthorizeNewPolicy;
251 TPMS_POLICYAUTHORIZATION *authorization = &command->authorization;
252 TPMS_POLICY *policy = &context->policy.policy;
253 TPMT_SIGNATURE *signature;
254 IFAPI_OBJECT ** keyObject = &context->Key_Sign.key_object;
255
256 switch (context->state) {
257 statecase(context->state, AUTHORIZE_NEW_LOAD_KEY);
258 /* Load the key used for signing the policy authorization. */
259 r = ifapi_load_key(context, command->signingKeyPath,
260 keyObject);
261 return_try_again(r);
262 goto_if_error(r, "Fapi sign.", cleanup);
263
264 fallthrough;
265
266 statecase(context->state, AUTHORIZE_NEW_CALCULATE_POLICY);
267 /*
268 * NameAlg of signing key will be used to compute the aHash digest.
269 * This NameAlg will also be used to compute the policy digest.
270 * Thus the NameAlg must be equal to the NameAlg of the object to
271 * be authorized.
272 */
273 hashAlg = (*keyObject)->misc.key.public.publicArea.nameAlg;
274
275 if (!(hashSize = ifapi_hash_get_digest_size(hashAlg))) {
276 goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED,
277 "Unsupported hash algorithm (%" PRIu16 ")",
278 cleanup, hashAlg);
279 }
280
281 /* Calculate the policy digest of the policy to be authorized. */
282 r = ifapi_calculate_tree(context,
283 command->policyPath, policy,
284 hashAlg, &digestIdx, &hashSize);
285 return_try_again(r);
286 goto_if_error(r, "Fapi calculate tree.", cleanup);
287
288 /* Compute the aHash from policy digest and policyRef */
289 r = ifapi_crypto_hash_start(&cryptoContext, hashAlg);
290 goto_if_error(r, "crypto hash start", cleanup);
291
292 HASH_UPDATE_BUFFER(cryptoContext,
293 &policy->
294 policyDigests.digests[digestIdx].digest, hashSize,
295 r, cleanup);
296 if (command->policyRef.size > 0) {
297 HASH_UPDATE_BUFFER(cryptoContext,
298 &command->policyRef.buffer[0],
299 command->policyRef.size, r, cleanup);
300 }
301 r = ifapi_crypto_hash_finish(&cryptoContext,
302 (uint8_t *) & aHash.buffer[0], &hashSize);
303 goto_if_error(r, "crypto hash finish", cleanup);
304
305 aHash.size = hashSize;
306 LOGBLOB_TRACE(&command->policyRef.buffer[0], command->policyRef.size, "policyRef");
307 LOGBLOB_TRACE(&aHash.buffer[0], aHash.size, "aHash");
308
309 fallthrough;
310
311 statecase(context->state, AUTHORIZE_NEW_KEY_SIGN_POLICY);
312 /* Perform the singing operation on the policy's aHash. */
313 r = ifapi_key_sign(context, *keyObject, NULL,
314 &aHash, &signature, &publicKey, NULL);
315 return_try_again(r);
316 goto_if_error(r, "Fapi sign.", cleanup);
317
318 SAFE_FREE(publicKey);
319
320 /* Store the signature results and cleanup remainters. */
321 authorization->signature = *signature;
322 authorization->policyRef = command->policyRef;
323 strdup_check(authorization->type, "tpm", r, cleanup);
324 authorization->key =
325 (*keyObject)->misc.key.public.publicArea;
326 SAFE_FREE(signature);
327 ifapi_cleanup_ifapi_object(*keyObject);
328
329 /* Extend the authorization to the policy stored. */
330 ifapi_extend_authorization(policy, authorization);
331 goto_if_null(policy->policyAuthorizations,
332 "Out of memory", TSS2_FAPI_RC_MEMORY, cleanup);
333
334 fallthrough;
335
336 statecase(context->state, AUTHORIZE_NEW_WRITE_POLICY_PREPARE);
337 /* Store the newly authorized policy in the policy store. */
338 r = ifapi_policy_store_store_async(&context->pstore, &context->io,
339 command->policyPath, policy);
340 goto_if_error_reset_state(r, "Could not open: %s", cleanup,
341 command->policyPath);
342
343 fallthrough;
344
345 statecase(context->state, AUTHORIZE_NEW_WRITE_POLICY);
346 r = ifapi_policy_store_store_finish(&context->pstore, &context->io);
347 return_try_again(r);
348 return_if_error_reset_state(r, "write_finish failed");
349
350 fallthrough;
351
352 statecase(context->state, AUTHORIZE_NEW_CLEANUP)
353 /* Cleanup and reset the context state. */
354 r = ifapi_cleanup_session(context);
355 try_again_or_error_goto(r, "Cleanup", cleanup);
356
357 context->state = _FAPI_STATE_INIT;
358 break;
359
360 statecasedefault(context->state);
361 }
362
363 cleanup:
364 /* Cleanup any intermediate results and state stored in the context. */
365 if (cryptoContext)
366 ifapi_crypto_hash_abort(&cryptoContext);
367 ifapi_session_clean(context);
368 ifapi_cleanup_policy(policy);
369 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
370 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
371 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
372 SAFE_FREE(command->policyPath);
373 SAFE_FREE(command->signingKeyPath);
374 LOG_TRACE("finished");
375 return r;
376 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23 #include "fapi_crypto.h"
24
25 /** One-Call function for Fapi_ChangeAuth
26 *
27 * Changes the Authorization data of an entity found at keyPath. The parameter
28 * authValue is a 0-terminated UTF-8 encoded password.
29 * If it is longer than the digest size of the entity's nameAlg, it will be
30 * hashed according the the TPM specification part 1, rev 138, section 19.6.4.3.
31 *
32 * @param[in,out] context The FAPI_CONTEXT
33 * @param[in] entityPath The path to the entity to modify
34 * @param[in] authValue The new 0-terminated password to set for the entity.
35 * May be NULL
36 *
37 * @retval TSS2_RC_SUCCESS: if the function call was a success.
38 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or entityPath is NULL.
39 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
40 * @retval TSS2_FAPI_RC_BAD_PATH: if entityPath does not map to a FAPI entity.
41 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
42 * operation already pending.
43 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
44 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
45 * internal operations or return parameters.
46 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
47 * config file.
48 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
49 * the function.
50 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
51 * during authorization.
52 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
53 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
54 * this function needs to be called again.
55 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
56 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
57 * is not set.
58 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
59 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
60 * was not successful.
61 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
62 */
63 TSS2_RC
64 Fapi_ChangeAuth(
65 FAPI_CONTEXT *context,
66 char const *entityPath,
67 char const *authValue)
68 {
69 LOG_TRACE("called for context:%p", context);
70
71 TSS2_RC r, r2;
72
73 /* Check for NULL parameters */
74 check_not_null(context);
75 check_not_null(entityPath);
76
77 /* Check whether TCTI and ESYS are initialized */
78 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
79 TSS2_FAPI_RC_NO_TPM);
80
81 /* If the async state automata of FAPI shall be tested, then we must not set
82 the timeouts of ESYS to blocking mode.
83 During testing, the mssim tcti will ensure multiple re-invocations.
84 Usually however the synchronous invocations of FAPI shall instruct ESYS
85 to block until a result is available. */
86 #ifndef TEST_FAPI_ASYNC
87 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
88 return_if_error_reset_state(r, "Set Timeout to blocking");
89 #endif /* TEST_FAPI_ASYNC */
90
91 r = Fapi_ChangeAuth_Async(context, entityPath, authValue);
92 return_if_error_reset_state(r, "Entity_ChangeAuth");
93
94 do {
95 /* We wait for file I/O to be ready if the FAPI state automata
96 are in a file I/O state. */
97 r = ifapi_io_poll(&context->io);
98 return_if_error(r, "Something went wrong with IO polling");
99
100 /* Repeatedly call the finish function, until FAPI has transitioned
101 through all execution stages / states of this invocation. */
102 r = Fapi_ChangeAuth_Finish(context);
103 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
104
105 /* Reset the ESYS timeout to non-blocking, immediate response. */
106 r2 = Esys_SetTimeout(context->esys, 0);
107 return_if_error(r2, "Set Timeout to non-blocking");
108
109 return_if_error_reset_state(r, "Entity_ChangeAuth");
110
111 LOG_TRACE("finished");
112 return TSS2_RC_SUCCESS;
113 }
114
115 /** Asynchronous function for Fapi_ChangeAuth
116 *
117 * Changes the Authorization data of an entity found at keyPath. The parameter
118 * authValue is a 0-terminated UTF-8 encoded password.
119 * If it is longer than the digest size of the entity's nameAlg, it will be
120 * hashed according the the TPM specification part 1, rev 138, section 19.6.4.3.
121 *
122 * Call Fapi_ChangeAuth_Finish to finish the execution of this command.
123
124 * @param[in,out] context The FAPI_CONTEXT
125 * @param[in] entityPath The path to the entity to modify
126 * @param[in] authValue The new 0-terminated password to set for the entity.
127 * May be NULL
128 *
129 * @retval TSS2_RC_SUCCESS: if the function call was a success.
130 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or entityPath is NULL.
131 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
132 * @retval TSS2_FAPI_RC_BAD_PATH: if entityPath does not map to a FAPI entity.
133 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
134 * operation already pending.
135 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
136 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
137 * internal operations or return parameters.
138 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
139 * the function.
140 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
141 * config file.
142 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
143 * during authorization.
144 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
145 */
146 TSS2_RC
147 Fapi_ChangeAuth_Async(
148 FAPI_CONTEXT *context,
149 char const *entityPath,
150 char const *authValue)
151 {
152 LOG_TRACE("called for context:%p", context);
153 LOG_TRACE("entityPath: %s", entityPath);
154 LOG_TRACE("authValue: %s", authValue);
155
156 TSS2_RC r;
157
158 /* Check for NULL parameters */
159 check_not_null(context);
160 check_not_null(entityPath);
161
162 /* Helpful pointer aliases */
163 IFAPI_Entity_ChangeAuth * command = &(context->cmd.Entity_ChangeAuth);
164
165 /* Reset all context-internal session state information. */
166 r = ifapi_session_init(context);
167 return_if_error(r, "Initialize Entity_ChangeAuth");
168
169 /* Copy parameters to context for use during _Finish. */
170 context->loadKey.parent_handle = ESYS_TR_NONE;
171 command->handle = ESYS_TR_NONE;
172 memset(&command->object, 0, sizeof(IFAPI_OBJECT));
173 strdup_check(command->entityPath, entityPath, r, error_cleanup);
174 if (authValue != NULL) {
175 strdup_check(command->authValue, authValue, r, error_cleanup);
176 } else {
177 strdup_check(command->authValue, "", r, error_cleanup);
178 }
179 command->handle = ESYS_TR_NONE;
180
181 /* Get a session for further authorizing and integrity checking the
182 subsequent ChangeAuth calls. */
183 r = ifapi_get_sessions_async(context,
184 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
185 TPMA_SESSION_DECRYPT, 0);
186 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
187
188 /* Copy new auth value to appropriate structure in context */
189 if (command->authValue) {
190 if (strlen(command->authValue) > sizeof(TPMU_HA)) {
191 LOG_ERROR("authValue to big. (Should be <= %zu", sizeof(TPMU_HA));
192 r = TSS2_FAPI_RC_BAD_VALUE;
193 goto error_cleanup;
194 }
195
196 command->newAuthValue.size =
197 strlen(command->authValue);
198 memcpy(&command->newAuthValue.buffer[0],
199 command->authValue,
200 command->newAuthValue.size);
201 } else {
202 command->newAuthValue.size = 0;
203 }
204
205 /* Initialize the context state for this operation. */
206 context->state = ENTITY_CHANGE_AUTH_WAIT_FOR_SESSION;
207
208 LOG_TRACE("finished");
209 return TSS2_RC_SUCCESS;
210
211 error_cleanup:
212 /* Cleanup duplicated input parameters that were copied before. */
213 SAFE_FREE(command->entityPath);
214 SAFE_FREE(command->authValue);
215 return r;
216 }
217
218 /** Asynchronous finish function for Fapi_ChangeAuth
219 *
220 * This function should be called after a previous Fapi_ChangeAuth_Async.
221 *
222 * @param[in,out] context The FAPI_CONTEXT
223 *
224 * @retval TSS2_RC_SUCCESS: if the function call was a success.
225 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
226 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
227 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
228 * operation already pending.
229 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
230 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
231 * internal operations or return parameters.
232 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
233 * complete. Call this function again later.
234 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
235 * the function.
236 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
237 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
238 * during authorization.
239 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
240 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
241 * is not set.
242 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
243 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
244 * was not successful.
245 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
246 */
247 TSS2_RC
248 Fapi_ChangeAuth_Finish(
249 FAPI_CONTEXT *context)
250 {
251 LOG_TRACE("called for context:%p", context);
252
253 TSS2_RC r;
254 ESYS_TR auth_session;
255
256 /* Check for NULL parameters */
257 check_not_null(context);
258
259 /* Helpful pointers */
260 IFAPI_Entity_ChangeAuth * command = &(context->cmd.Entity_ChangeAuth);
261 IFAPI_OBJECT * object = &command->object;
262 const IFAPI_PROFILE *profile;
263
264 switch (context->state) {
265 statecase(context->state, ENTITY_CHANGE_AUTH_WAIT_FOR_SESSION)
266 /* Retrieve profile information for subsequent commands. */
267 r = ifapi_profiles_get(&context->profiles, command->entityPath,
268 &profile);
269 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
270
271 /* Finish starting the session establishment. */
272 r = ifapi_get_sessions_finish(context, profile, profile->nameAlg);
273 return_try_again(r);
274
275 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
276
277 /* If the referenced entity is an NV-Index, load its metadata from
278 the keystore. */
279 if (ifapi_path_type_p(command->entityPath,
280 IFAPI_NV_PATH)) {
281 r = ifapi_keystore_load_async(&context->keystore, &context->io,
282 command->entityPath);
283 return_if_error_reset_state(r, "Could not open: %s",
284 command->entityPath);
285
286 /* Set the correct re-entry state for handling NV-index entities. */
287 context->state = ENTITY_CHANGE_AUTH_WAIT_FOR_NV_READ;
288 return TSS2_FAPI_RC_TRY_AGAIN;
289 }
290
291 /* Check if the referenced entity is a hierarchy. */
292 command->hierarchy_handle =
293 ifapi_get_hierary_handle(command->entityPath);
294
295 if (command->hierarchy_handle) {
296 /* Set the correct re-entry state for handling hierarchies. */
297 context->state = ENTITY_CHANGE_AUTH_HIERARCHY_READ;
298 /* Load the hierarchy's metadata from the keystore. */
299 r = ifapi_keystore_load_async(&context->keystore, &context->io,
300 command->entityPath);
301 return_if_error_reset_state(r, "Could not open: %s",
302 command->entityPath);
303
304 return TSS2_FAPI_RC_TRY_AGAIN;
305 }
306
307 /* At this point, the referenced entity must be a key.
308 Load the key's metadata from the keystore. */
309 r = ifapi_load_keys_async(context, command->entityPath);
310 goto_if_error(r, "Load keys.", error_cleanup);
311
312 fallthrough;
313
314 statecase(context->state, ENTITY_CHANGE_AUTH_WAIT_FOR_KEY)
315 r = ifapi_load_keys_finish(context, IFAPI_NOT_FLUSH_PARENT,
316 &command->handle,
317 &command->key_object);
318 return_try_again(r);
319
320 fallthrough;
321
322 statecase(context->state, ENTITY_CHANGE_AUTH_WAIT_FOR_KEY_AUTH)
323 /* Authorize the object with the old authorization */
324 object = command->key_object;
325 r = ifapi_authorize_object(context, object, &auth_session);
326 return_try_again(r);
327 goto_if_error_reset_state(r, "Authorize key.", error_cleanup);
328
329 /* Call to change the Authorization of the key. */
330 r = Esys_ObjectChangeAuth_Async(context->esys,
331 command->handle,
332 context->loadKey.parent_handle,
333 auth_session,
334 ESYS_TR_NONE, ESYS_TR_NONE,
335 &command->newAuthValue);
336 goto_if_error(r, "Error: Sign", error_cleanup);
337
338 fallthrough;
339
340 statecase(context->state, ENTITY_CHANGE_AUTH_AUTH_SENT)
341 r = Esys_ObjectChangeAuth_Finish(context->esys,
342 &command->newPrivate);
343 return_try_again(r);
344
345 goto_if_error(r, "Error: Entity ChangeAuth", error_cleanup);
346
347 object = command->key_object;
348 object->misc.key.private.size = command->newPrivate->size;
349
350 /* Store the new private key blob to the context to be stored to
351 the keystore. */
352 free(object->misc.key.private.buffer);
353 object->misc.key.private.buffer = malloc(object->misc.key.private.size);
354 goto_if_null2(object->misc.key.private.buffer, "Out of memory.",
355 r, TSS2_FAPI_RC_MEMORY, error_cleanup);
356
357 memcpy(object->misc.key.private.buffer,
358 &command->newPrivate->buffer[0],
359 object->misc.key.private.size);
360 free(command->newPrivate);
361
362 /* Flush the key with the old authorization form the TPM. */
363 r = Esys_FlushContext_Async(context->esys,
364 command->handle);
365 goto_if_error(r, "Error: FlushContext", error_cleanup);
366
367 command->handle = ESYS_TR_NONE;
368
369 fallthrough;
370
371 statecase(context->state, ENTITY_CHANGE_AUTH_WAIT_FOR_FLUSH)
372 r = Esys_FlushContext_Finish(context->esys);
373 return_try_again(r);
374
375 goto_if_error(r, "Error: ObjectChangeAuth", error_cleanup);
376
377 /* Flush the parent key as well. */
378 if (!context->loadKey.parent_handle_persistent
379 && context->loadKey.parent_handle != ESYS_TR_NONE) {
380 r = Esys_FlushContext_Async(context->esys, context->loadKey.parent_handle);
381 goto_if_error(r, "Flush parent", error_cleanup);
382
383 context->loadKey.parent_handle = ESYS_TR_NONE;
384 return TSS2_FAPI_RC_TRY_AGAIN;
385 }
386
387 /* Store information about whether the new authorization is an
388 empty authorization or an actual password. */
389 object = command->key_object;
390
391 if (strlen(command->authValue) > 0)
392 object->misc.key.with_auth = TPM2_YES;
393 else
394 object->misc.key.with_auth = TPM2_NO;
395 fallthrough;
396
397 statecase(context->state, ENTITY_CHANGE_AUTH_WRITE_PREPARE)
398 /* Perform serialization of the esys object if necessary */
399 r = ifapi_esys_serialize_object(context->esys, object);
400 goto_if_error(r, "Prepare serialization", error_cleanup);
401
402 /* Start writing the NV object to the key store */
403 r = ifapi_keystore_store_async(&context->keystore, &context->io,
404 command->entityPath,
405 object);
406 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
407 command->entityPath);
408 fallthrough;
409
410 statecase(context->state, ENTITY_CHANGE_AUTH_WRITE)
411 /* Finish writing the object to the key store */
412 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
413 return_try_again(r);
414 return_if_error_reset_state(r, "write_finish failed");
415
416 fallthrough;
417
418 statecase(context->state, ENTITY_CHANGE_AUTH_CLEANUP)
419 /* Clean up the session information and reset the state and be done. */
420 r = ifapi_cleanup_session(context);
421 try_again_or_error_goto(r, "Cleanup", error_cleanup);
422
423 context->state = _FAPI_STATE_INIT;
424 LOG_TRACE("success");
425 break;
426
427 statecase(context->state, ENTITY_CHANGE_AUTH_WAIT_FOR_NV_READ)
428 /* The is the re-entry in case of an NV-index as referenced object.
429 All code between the check for the entity type above and this
430 place was skipped in case of an NV-index. */
431 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
432 &command->object);
433 return_try_again(r);
434 return_if_error_reset_state(r, "read_finish failed");
435
436 /* Initialize the esys-object for the NV-index. */
437 r = ifapi_initialize_object(context->esys, &command->object);
438 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
439
440 fallthrough;
441
442 statecase(context->state, ENTITY_CHANGE_AUTH_WAIT_FOR_NV_AUTH)
443 /* Authorize the object with with the policies
444 auth value and command code */
445 r = ifapi_authorize_object(context, object, &auth_session);
446 return_try_again(r);
447 goto_if_error(r, "Authorize NV object.", error_cleanup);
448
449 /* Change the NV index's AuthValue. */
450 r = Esys_NV_ChangeAuth_Async(context->esys,
451 context->nv_cmd.nv_object.handle,
452 auth_session,
453 ESYS_TR_NONE,
454 ESYS_TR_NONE,
455 &command->newAuthValue);
456 goto_if_error(r, "Error: NV_ChangeAuth", error_cleanup);
457
458 fallthrough;
459
460 statecase(context->state, ENTITY_CHANGE_AUTH_WAIT_FOR_NV_CHANGE_AUTH)
461 r = Esys_NV_ChangeAuth_Finish(context->esys);
462 return_try_again(r);
463
464 goto_if_error(r, "Error: Entity ChangeAuth", error_cleanup);
465
466 /* Update the information about whether the new Auth is an empty
467 authorization or an actual password. */
468 if (strlen(command->authValue) > 0)
469 object->misc.nv.with_auth = TPM2_YES;
470 else
471 object->misc.nv.with_auth = TPM2_NO;
472
473 /* Jump over to the AUTH_WRITE_PREPARE state for storing the
474 new metadata to the keystore. */
475 context->state = ENTITY_CHANGE_AUTH_WRITE_PREPARE;
476 return TSS2_FAPI_RC_TRY_AGAIN;
477
478 statecase(context->state, ENTITY_CHANGE_AUTH_HIERARCHY_READ)
479 /* This is the re-entry point if the referenced entity is a
480 hierarchy. All code between the check for the entity type
481 and this place is skipped in case of a hierarchy. */
482 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
483 return_try_again(r);
484 return_if_error_reset_state(r, "read_finish failed");
485
486 /* Initialize the esys object for the hierarhcy. */
487 r = ifapi_initialize_object(context->esys, &command->object);
488 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
489
490 command->object.handle
491 = command->hierarchy_handle;
492
493 fallthrough;
494
495 statecase(context->state, ENTITY_CHANGE_AUTH_HIERARCHY_AUTHORIZE)
496 /* Authorize against the hierarhcy. */
497 r = ifapi_authorize_object(context, &command->object, &auth_session);
498 return_try_again(r);
499 goto_if_error(r, "Authorize hierarchy.", error_cleanup);
500
501 fallthrough;
502
503 statecase(context->state, ENTITY_CHANGE_AUTH_HIERARCHY_CHANGE_AUTH)
504 /* Change the hierarchy authorization. */
505 r = ifapi_change_auth_hierarchy(context,
506 command->hierarchy_handle,
507 &command->object,
508 &command->newAuthValue);
509 return_try_again(r);
510 goto_if_error(r, "Change auth hierarchy.", error_cleanup);
511
512 /* Jump over to the AUTH_WRITE_PREPARE state for storing the
513 new metadata to the keystore. */
514 context->state = ENTITY_CHANGE_AUTH_WRITE_PREPARE;
515 return TSS2_FAPI_RC_TRY_AGAIN;
516
517 statecasedefault(context->state);
518 }
519
520 error_cleanup:
521 /* In error cases object might not be flushed. */
522 if (context->loadKey.parent_handle != ESYS_TR_NONE)
523 Esys_FlushContext(context->esys, context->loadKey.parent_handle);
524 if (command->handle != ESYS_TR_NONE)
525 Esys_FlushContext(context->esys, command->handle);
526 ifapi_session_clean(context);
527 ifapi_cleanup_ifapi_object(object);
528 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
529 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
530 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
531 ifapi_cleanup_ifapi_object(command->key_object);
532 SAFE_FREE(command->entityPath);
533 SAFE_FREE(command->authValue);
534 LOG_TRACE("finished");
535 return r;
536 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "fapi_policy.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 /** One-Call function for Fapi_CreateKey
26 *
27 * Creates a key inside the TPM based on the Key type, using the supplied
28 * policy and authValue. The key is then stored either in the FAPI metadata
29 * store or the TPM.
30 *
31 * @param[in,out] context The FAPI_CONTEXT
32 * @param[in] path The path where the new key is stored
33 * @param[in] type The type of the new key. May be NULL
34 * @param[in] policyPath The path to the policy that is associated with the new
35 * key. May be NULL
36 * @param[in] authValue The authorization value for the new key. May be NULL
37 *
38 * @retval TSS2_RC_SUCCESS: if the function call was a success.
39 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
40 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
41 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
42 * a FAPI policy.
43 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if the parent key does not map to a FAPI
44 * key.
45 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a file already exists at path.
46 * @retval TSS2_FAPI_RC_BAD_VALUE: if the keyType is non-NULL and invalid.
47 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
48 * operation already pending.
49 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
50 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
51 * internal operations or return parameters.
52 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
53 * config file.
54 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
55 * this function needs to be called again.
56 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
57 * is not set.
58 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
59 */
60 TSS2_RC
61 Fapi_CreateKey(
62 FAPI_CONTEXT *context,
63 char const *path,
64 char const *type,
65 char const *policyPath,
66 char const *authValue)
67 {
68 LOG_TRACE("called for context:%p", context);
69
70 TSS2_RC r, r2;
71
72 /* Check for NULL parameters */
73 check_not_null(context);
74 check_not_null(path);
75
76 /* Check whether TCTI and ESYS are initialized */
77 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
78 TSS2_FAPI_RC_NO_TPM);
79
80 /* If the async state automata of FAPI shall be tested, then we must not set
81 the timeouts of ESYS to blocking mode.
82 During testing, the mssim tcti will ensure multiple re-invocations.
83 Usually however the synchronous invocations of FAPI shall instruct ESYS
84 to block until a result is available. */
85 #ifndef TEST_FAPI_ASYNC
86 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
87 return_if_error_reset_state(r, "Set Timeout to blocking");
88 #endif /* TEST_FAPI_ASYNC */
89
90 r = Fapi_CreateKey_Async(context, path, type, policyPath, authValue);
91 return_if_error_reset_state(r, "Key_Create");
92
93 do {
94 /* We wait for file I/O to be ready if the FAPI state automata
95 are in a file I/O state. */
96 r = ifapi_io_poll(&context->io);
97 return_if_error(r, "Something went wrong with IO polling");
98
99 /* Repeatedly call the finish function, until FAPI has transitioned
100 through all execution stages / states of this invocation. */
101 r = Fapi_CreateKey_Finish(context);
102 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
103
104 /* Reset the ESYS timeout to non-blocking, immediate response. */
105 r2 = Esys_SetTimeout(context->esys, 0);
106 return_if_error(r2, "Set Timeout to non-blocking");
107
108 return_if_error_reset_state(r, "Key_Create");
109
110 return TSS2_RC_SUCCESS;
111 }
112
113 /** Asynchronous function for Fapi_CreateKey
114 *
115 * Creates a key inside the TPM based on the Key type, using the supplied
116 * policy and authValue. The key is then stored either in the FAPI metadata
117 * store or the TPM.
118 *
119 * Call Fapi_CreateKey_Finish to finish the execution of this command.
120 *
121 * @param[in,out] context The FAPI_CONTEXT
122 * @param[in] path The path where the new key is stored
123 * @param[in] type The type of the new key. May be NULL
124 * @param[in] policyPath The path to the policy that is associated with the new
125 * key. May be NULL
126 * @param[in] authValue The authorization value for the new key. May be NULL
127 *
128 * @retval TSS2_RC_SUCCESS: if the function call was a success.
129 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
130 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
131 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
132 * a FAPI policy.
133 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if the parent key does not map to a FAPI
134 * key.
135 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a file already exists at path.
136 * @retval TSS2_FAPI_RC_BAD_VALUE: if the keyType is non-NULL and invalid.
137 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
138 * operation already pending.
139 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
140 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
141 * internal operations or return parameters.
142 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
143 * config file.
144 */
145 TSS2_RC
146 Fapi_CreateKey_Async(
147 FAPI_CONTEXT *context,
148 char const *path,
149 char const *type,
150 char const *policyPath,
151 char const *authValue)
152 {
153 LOG_TRACE("called for context:%p", context);
154 LOG_TRACE("path: %s", path);
155 LOG_TRACE("type: %s", type);
156 LOG_TRACE("policyPath: %s", policyPath);
157 LOG_TRACE("authValue: %s", authValue);
158
159 TSS2_RC r;
160
161 /* Check for NULL parameters */
162 check_not_null(context);
163 check_not_null(path);
164
165 /* Reset all context-internal session state information. */
166 r = ifapi_session_init(context);
167 return_if_error(r, "Initialize CreateKey");
168
169 /* Prepare the key creation with the authValue.
170 This will also copy the input information for use during the finish call. */
171 r = ifapi_key_create_prepare_auth(context, path, policyPath, authValue);
172 return_if_error(r, "Key create.");
173
174 /* Set the flags of the key to be created. If no type is given the empty-string
175 default type flags are set. If no policy is given, userWithAuth flag is set. */
176 r = ifapi_set_key_flags(type ? type : "",
177 (policyPath && strcmp(policyPath, "") != 0) ? true : false,
178 &context->cmd.Key_Create.public_templ);
179 return_if_error(r, "Set key flags for key");
180
181 /* Initialize the context state for this operation. */
182 context->state = KEY_CREATE;
183 LOG_TRACE("finished");
184 return TSS2_RC_SUCCESS;
185 }
186
187 /** Asynchronous finish function for Fapi_CreateKey
188 *
189 * This function should be called after a previous Fapi_CreateKey_Async.
190 *
191 * @param[in,out] context The FAPI_CONTEXT
192 *
193 * @retval TSS2_RC_SUCCESS: if the function call was a success.
194 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
195 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
196 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
197 * operation already pending.
198 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
199 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
200 * internal operations or return parameters.
201 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
202 * complete. Call this function again later.
203 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
204 * the function.
205 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
206 * is not set.
207 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
208 */
209 TSS2_RC
210 Fapi_CreateKey_Finish(
211 FAPI_CONTEXT *context)
212 {
213 LOG_TRACE("called for context:%p", context);
214
215 TSS2_RC r;
216
217 /* Check for NULL parameters */
218 check_not_null(context);
219
220 /* Helpful alias pointers */
221 IFAPI_Key_Create * command = &context->cmd.Key_Create;
222
223 switch (context->state) {
224 statecase(context->state, KEY_CREATE);
225 /* Finish the key creation inside the helper function. */
226 r = ifapi_key_create(context, &command->public_templ);
227 return_try_again(r);
228 goto_if_error(r, "Key create", error_cleanup);
229
230 /* Cleanup any intermediate results and state stored in the context. */
231 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
232 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
233 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
234 context->state = _FAPI_STATE_INIT;
235 LOG_TRACE("finished");
236 return TSS2_RC_SUCCESS;
237
238 statecasedefault(context->state);
239 }
240
241 error_cleanup:
242 /* Cleanup any intermediate results and state stored in the context. */
243 context->cmd.Key_Create.state = KEY_CREATE_INIT;
244 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
245 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
246 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
247 LOG_TRACE("finished");
248 return r;
249 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <errno.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "fapi_policy.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 /** One-Call function for Fapi_CreateNv
26 *
27 * This command creates an NV index in the TPM using a given path and type.
28 *
29 * @param[in,out] context The FAPI_CONTEXT
30 * @param[in] path The path to the new NV index
31 * @param[in] type The intended type of the new NV index. May be NULL
32 * @param[in] size The size of the new NV index in bytes. May be 0 if the size
33 * is inferred from the type
34 * @param[in] policyPath The path to the policy that is associated with the new
35 * NV index. May be NULL
36 * @param[in] authValue The authorization value that is associated with the new
37 * NV index. May be NULL
38 *
39 * @retval TSS2_RC_SUCCESS: if the function call was a success.
40 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
41 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
42 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if an NV index already exists at
43 * path.
44 * @retval TSS2_FAPI_RC_BAD_VALUE: if type is non-NULL but invalid or does not
45 * match the size.
46 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
47 * a FAPI policy or if path dos not refer to a valid NV index path.
48 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
49 * operation already pending.
50 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
51 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
52 * internal operations or return parameters.
53 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
54 * config file.
55 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
56 * this function needs to be called again.
57 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
58 * during authorization.
59 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
60 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
61 * @retval TSS2_FAPI_RC_NV_TOO_SMALL if too many NV handles are defined.
62 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
63 * is not set.
64 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
65 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
66 * was not successful.
67 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
68 */
69 TSS2_RC
70 Fapi_CreateNv(
71 FAPI_CONTEXT *context,
72 char const *path,
73 char const *type,
74 size_t size,
75 char const *policyPath,
76 char const *authValue)
77 {
78 LOG_TRACE("called for context:%p", context);
79
80 TSS2_RC r, r2;
81
82 /* Check for NULL parameters */
83 check_not_null(context);
84 check_not_null(path);
85
86 /* Check whether TCTI and ESYS are initialized */
87 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
88 TSS2_FAPI_RC_NO_TPM);
89
90 /* If the async state automata of FAPI shall be tested, then we must not set
91 the timeouts of ESYS to blocking mode.
92 During testing, the mssim tcti will ensure multiple re-invocations.
93 Usually however the synchronous invocations of FAPI shall instruct ESYS
94 to block until a result is available. */
95 #ifndef TEST_FAPI_ASYNC
96 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
97 return_if_error_reset_state(r, "Set Timeout to blocking");
98 #endif /* TEST_FAPI_ASYNC */
99
100 r = Fapi_CreateNv_Async(context, path, type, size,
101 policyPath, authValue);
102 return_if_error_reset_state(r, "NV_CreateWithTemplate");
103
104 do {
105 /* We wait for file I/O to be ready if the FAPI state automata
106 are in a file I/O state. */
107 r = ifapi_io_poll(&context->io);
108 return_if_error(r, "Something went wrong with IO polling");
109
110 /* Repeatedly call the finish function, until FAPI has transitioned
111 through all execution stages / states of this invocation. */
112 r = Fapi_CreateNv_Finish(context);
113 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
114
115 /* Reset the ESYS timeout to non-blocking, immediate response. */
116 r2 = Esys_SetTimeout(context->esys, 0);
117 return_if_error(r2, "Set Timeout to non-blocking");
118
119 return_if_error_reset_state(r, "NV_CreateWithTemplate");
120
121 return TSS2_RC_SUCCESS;
122 }
123
124 /** Asynchronous function for Fapi_CreateNv
125 *
126 * This command creates an NV index in the TPM using a given path and type.
127 *
128 * Call Fapi_CreateNv_Finish to finish the execution of this command.
129 *
130 * @param[in,out] context The FAPI_CONTEXT
131 * @param[in] path The path to the new NV index
132 * @param[in] type The intended type of the new NV index. May be NULL
133 * @param[in] size The size of the new NV index in bytes. May be 0 if the size
134 * is inferred from the type
135 * @param[in] policyPath The path to the policy that is associated with the new
136 * NV index. May be NULL
137 * @param[in] authValue The authorization value that is associated with the new
138 * NV index. May be NULL
139 *
140 * @retval TSS2_RC_SUCCESS: if the function call was a success.
141 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
142 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
143 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if an NV index already exists at
144 * path.
145 * @retval TSS2_FAPI_RC_BAD_VALUE: if type is non-NULL but invalid or does not
146 * match the size.
147 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
148 * a FAPI policy or if path dos not refer to a valid NV index path.
149 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
150 * operation already pending.
151 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
152 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
153 * internal operations or return parameters.
154 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
155 * config file.
156 */
157 TSS2_RC
158 Fapi_CreateNv_Async(
159 FAPI_CONTEXT *context,
160 char const *path,
161 char const *type,
162 size_t size,
163 char const *policyPath,
164 char const *authValue)
165 {
166 LOG_TRACE("called for context:%p", context);
167 LOG_TRACE("path: %s", path);
168 LOG_TRACE("type: %s", type);
169 LOG_TRACE("size: %zi", size);
170 LOG_TRACE("policyPath: %s", policyPath);
171 LOG_TRACE("authValue: %s", authValue);
172
173 TSS2_RC r;
174
175 /* Check for NULL parameters */
176 check_not_null(context);
177 check_not_null(path);
178
179 /* Helpful alias pointers */
180 IFAPI_NV_Cmds * nvCmd = &(context->nv_cmd);
181 TPM2B_AUTH *auth = &nvCmd->auth;
182 IFAPI_NV * miscNv = &(nvCmd->nv_object.misc.nv);
183
184 /* Reset all context-internal session state information. */
185 r = ifapi_session_init(context);
186 return_if_error(r, "Initialize NV_CreateNv");
187
188 /* First check whether an existing object would be overwritten */
189 r = ifapi_keystore_check_overwrite(&context->keystore, &context->io,
190 path);
191 return_if_error2(r, "Check overwrite %s", path);
192
193 /* Copy parameters to context for use during _Finish. */
194 memset(&context->nv_cmd, 0, sizeof(IFAPI_NV_Cmds));
195 if (authValue) {
196 if (strlen(authValue) > sizeof(TPMU_HA)) {
197 return_error(TSS2_FAPI_RC_BAD_VALUE, "AuthValue too long");
198 }
199
200 auth->size = strlen(authValue);
201 memcpy(&auth->buffer[0], authValue, auth->size);
202 } else {
203 auth->size = 0;
204 }
205 strdup_check(nvCmd->nvPath, path, r, error_cleanup);
206 nvCmd->numBytes = size;
207 nvCmd->nv_object.objectType = IFAPI_NV_OBJ;
208 strdup_check(miscNv->policyInstance, policyPath, r, error_cleanup);
209
210 /* Set the flags of the NV index to be created. If no type is given the empty-string
211 default type flags are set. */
212 r = ifapi_set_nv_flags(type ? type : "", &nvCmd->public_templ,
213 policyPath);
214 goto_if_error(r, "Set key flags for NV object", error_cleanup);
215
216 /* Initialize the context state for this operation. */
217 context->state = NV_CREATE_READ_PROFILE;
218 LOG_TRACE("finished");
219 return TSS2_RC_SUCCESS;
220
221 error_cleanup:
222 /* Cleanup duplicated input parameters that were copied before. */
223 SAFE_FREE(nvCmd->nvPath);
224 SAFE_FREE(miscNv->policyInstance);
225 return r;
226 }
227
228 /** Asynchronous finish function for Fapi_CreateNv
229 *
230 * This function should be called after a previous Fapi_CreateNv_Async.
231 *
232 * @param[in,out] context The FAPI_CONTEXT
233 *
234 * @retval TSS2_RC_SUCCESS: if the function call was a success.
235 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
236 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
237 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
238 * operation already pending.
239 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
240 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
241 * internal operations or return parameters.
242 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
243 * complete. Call this function again later.
244 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
245 * the function.
246 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
247 * during authorization.
248 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
249 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
250 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
251 * @retval TSS2_FAPI_RC_NV_TOO_SMALL if too many NV handles are defined.
252 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
253 * is not set.
254 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
255 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
256 * was not successful.
257 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
258 */
259 TSS2_RC
260 Fapi_CreateNv_Finish(
261 FAPI_CONTEXT *context)
262 {
263 LOG_TRACE("called for context:%p", context);
264
265 TSS2_RC r;
266 ESYS_TR nvHandle;
267
268 /* Check for NULL parameters */
269 check_not_null(context);
270
271 /* Helpful alias pointers */
272 IFAPI_NV_Cmds * nvCmd = &(context->nv_cmd);
273 TPM2B_AUTH *auth = &nvCmd->auth;
274 IFAPI_OBJECT *hierarchy = &nvCmd->auth_object;
275 IFAPI_NV * miscNv = &(nvCmd->nv_object.misc.nv);
276 TPM2B_NV_PUBLIC *publicInfo = &miscNv->public;
277 TPM2B_DIGEST * authPolicy = &(miscNv->public.nvPublic.authPolicy);
278 TPMS_POLICY * policy = &(context->policy.policy);
279 TPMS_POLICY ** nvCmdPolicy = &nvCmd->nv_object.policy;
280 ESYS_TR auth_session;
281
282 switch (context->state) {
283 statecase(context->state, NV_CREATE_READ_PROFILE)
284 /* Mix the provided flags provided via the type with with template
285 of the current active crypto profile. */
286 r = ifapi_merge_profile_into_nv_template(context,
287 &nvCmd->public_templ);
288 goto_if_error_reset_state(r, "Merge profile", error_cleanup);
289
290 /* Store information from template in context */
291 miscNv->description = NULL;
292 publicInfo->nvPublic = nvCmd->public_templ.public;
293
294 /* Check that the hierarchy for the NV index to be created is "Owner".
295 FAPI does not allow the creation of "Platform" NV indexes. */
296 if (nvCmd->public_templ.hierarchy == TPM2_RH_OWNER) {
297 miscNv->hierarchy = ESYS_TR_RH_OWNER;
298 } else {
299 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong hierarchy", error_cleanup);
300 }
301
302 /* Load the Storage Hierarchy "Owner" meta data for used during
303 NV creation authorization. */
304 r = ifapi_keystore_load_async(&context->keystore, &context->io, "HS");
305 return_if_error_reset_state(r, "Could not open storage hierarchy HS");
306 fallthrough;
307
308 statecase(context->state, NV_CREATE_READ_HIERARCHY)
309 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
310 &nvCmd->auth_object);
311 return_try_again(r);
312 goto_if_error_reset_state(r, "read_finish failed", error_cleanup);
313
314 /* Initialize the esys object for the hierarchy. */
315 r = ifapi_initialize_object(context->esys, &nvCmd->auth_object);
316 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
317
318 nvCmd->auth_object.handle
319 = miscNv->hierarchy;
320
321 /* Check if a policy is set for the NV index to be created. */
322 if (miscNv->policyInstance &&
323 strcmp(miscNv->policyInstance, "") != 0)
324 nvCmd->skip_policy_computation = false;
325 else
326 nvCmd->skip_policy_computation = true;
327 fallthrough;
328
329 statecase(context->state, NV_CREATE_CALCULATE_POLICY)
330 if (!nvCmd->skip_policy_computation) {
331 /* Calculate the policy as read for the keystore. */
332 r = ifapi_calculate_tree(context,
333 miscNv->policyInstance,
334 policy,
335 miscNv->public.nvPublic.nameAlg,
336 &context->policy.digest_idx,
337 &context->policy.hash_size);
338 return_try_again(r);
339
340 goto_if_error2(r, "Calculate policy tree %s", error_cleanup,
341 context->cmd.Key_Create.policyPath);
342
343 /* Store the calculated policy in the NV object */
344 *nvCmdPolicy = calloc(1,
345 sizeof(TPMS_POLICY));
346 goto_if_null(*nvCmdPolicy,
347 "Out of memory,", TSS2_FAPI_RC_MEMORY, error_cleanup);
348 **(nvCmdPolicy) = *policy;
349
350 authPolicy->size =
351 context->policy.hash_size;
352 memcpy(&authPolicy->buffer[0],
353 &policy->policyDigests.digests[context->policy.digest_idx].digest,
354 context->policy.hash_size);
355 LOGBLOB_TRACE(
356 &authPolicy->buffer[0],
357 context->policy.hash_size, "Create Key Policy");
358 }
359 fallthrough;
360
361 statecase(context->state, NV_CREATE_GET_INDEX)
362 r = ifapi_get_nv_start_index(nvCmd->nvPath,
363 &publicInfo->nvPublic.nvIndex);
364 goto_if_error_reset_state(r, "FAPI get handle index.", error_cleanup);
365
366 /* We are searching for a new free NV-index handle. */
367 r = ifapi_get_free_handle_async(context, &publicInfo->nvPublic.nvIndex);
368 goto_if_error_reset_state(r, "FAPI get handle index.", error_cleanup);
369 nvCmd->maxNvIndex = publicInfo->nvPublic.nvIndex + 100;
370
371 fallthrough;
372
373 statecase(context->state, NV_CREATE_FIND_INDEX)
374 r = ifapi_get_free_handle_finish(context, &publicInfo->nvPublic.nvIndex,
375 nvCmd->maxNvIndex);
376 return_try_again(r);
377 goto_if_error_reset_state(r, "FAPI get handle index.", error_cleanup);
378
379 /* Start a authorization session for the NV creation. */
380 context->primary_state = PRIMARY_INIT;
381 r = ifapi_get_sessions_async(context,
382 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
383 0, 0);
384 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
385 fallthrough;
386
387 statecase(context->state, NV_CREATE_WAIT_FOR_SESSION)
388 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
389 context->profiles.default_profile.nameAlg);
390 return_try_again(r);
391 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
392
393
394 fallthrough;
395
396 statecase(context->state, NV_CREATE_AUTHORIZE_HIERARCHY)
397 /* Authorize with the storage hierarhcy / "owner" for NV creation. */
398 r = ifapi_authorize_object(context, &nvCmd->auth_object, &auth_session);
399 FAPI_SYNC(r, "Authorize hierarchy.", error_cleanup);
400
401 /* Create the NV Index. */
402 r = Esys_NV_DefineSpace_Async(context->esys,
403 hierarchy->handle,
404 auth_session,
405 ESYS_TR_NONE,
406 ESYS_TR_NONE,
407 auth,
408 publicInfo);
409 goto_if_error_reset_state(r, " Fapi_CreateNv_Async", error_cleanup);
410 fallthrough;
411
412 statecase(context->state, NV_CREATE_AUTH_SENT)
413 r = Esys_NV_DefineSpace_Finish(context->esys, &nvHandle);
414 return_try_again(r);
415
416 goto_if_error_reset_state(r, "FAPI CreateWithTemplate_Finish", error_cleanup);
417
418 /* Store whether the NV index requires a password. */
419 nvCmd->nv_object.handle = nvHandle;
420 if (nvCmd->auth.size > 0)
421 miscNv->with_auth = TPM2_YES;
422 else
423 miscNv->with_auth = TPM2_NO;
424
425 /* Perform esys serialization if necessary */
426 r = ifapi_esys_serialize_object(context->esys, &nvCmd->nv_object);
427 goto_if_error(r, "Prepare serialization", error_cleanup);
428
429 /* Start writing the NV object to the key store */
430 r = ifapi_keystore_store_async(&context->keystore, &context->io,
431 nvCmd->nvPath,
432 &nvCmd->nv_object);
433 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
434 nvCmd->nvPath);
435
436 fallthrough;
437
438 statecase(context->state, NV_CREATE_WRITE)
439 /* Finish writing the NV object to the key store */
440 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
441 return_try_again(r);
442 return_if_error_reset_state(r, "write_finish failed");
443
444 break;
445
446 statecasedefault(context->state);
447 }
448
449 context->state = _FAPI_STATE_INIT;
450 LOG_DEBUG("success");
451 r = TSS2_RC_SUCCESS;
452
453 error_cleanup:
454 /* Cleanup any intermediate results and state stored in the context. */
455 ifapi_cleanup_ifapi_object(&nvCmd->nv_object);
456 ifapi_cleanup_ifapi_object(&nvCmd->auth_object);
457 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
458 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
459 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
460 SAFE_FREE(miscNv->policyInstance);
461 SAFE_FREE(nvCmd->nvPath);
462 ifapi_session_clean(context);
463 LOG_TRACE("finished");
464 return r;
465 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "fapi_policy.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 /** One-Call function for Fapi_CreateSeal
26 *
27 * Creates a sealed object and stores it in the FAPI metadata store. If no data
28 * is provided, the TPM generates random data to fill the sealed object.
29 *
30 * @param[in,out] context The FAPI_CONTEXT
31 * @param[in] path The path to the new sealed object
32 * @param[in] type The type of the new sealed object. May be NULL
33 * @param[in] size The size of the new sealed object. Must not be 0
34 * @param[in] policyPath The path to the policy that is associated with the new
35 * sealed object. May be NULL
36 * @param[in] authValue The authorization value for the new sealed object. May
37 * be NULL
38 * @param[in] data The data that is to be sealed within the new object. May be
39 * NULL
40 *
41 * @retval TSS2_RC_SUCCESS: if the function call was a success.
42 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, or path is NULL.
43 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
44 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if the parent key does not map to a
45 * FAPI key.
46 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
47 * a FAPI key.
48 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a sealed object already exists
49 * at path.
50 * @retval TSS2_FAPI_RC_BAD_VALUE: if the keyType is invalid.
51 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
52 * operation already pending.
53 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
54 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
55 * internal operations or return parameters.
56 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
57 * config file.
58 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
59 * this function needs to be called again.
60 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
61 * is not set.
62 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
63 */
64 TSS2_RC
65 Fapi_CreateSeal(
66 FAPI_CONTEXT *context,
67 char const *path,
68 char const *type,
69 size_t size,
70 char const *policyPath,
71 char const *authValue,
72 uint8_t const *data)
73 {
74 LOG_TRACE("called for context:%p", context);
75
76 TSS2_RC r, r2;
77
78 /* Check for NULL parameters */
79 check_not_null(context);
80 check_not_null(path);
81
82 /* Check whether TCTI and ESYS are initialized */
83 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
84 TSS2_FAPI_RC_NO_TPM);
85
86 /* If the async state automata of FAPI shall be tested, then we must not set
87 the timeouts of ESYS to blocking mode.
88 During testing, the mssim tcti will ensure multiple re-invocations.
89 Usually however the synchronous invocations of FAPI shall instruct ESYS
90 to block until a result is available. */
91 #ifndef TEST_FAPI_ASYNC
92 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
93 return_if_error_reset_state(r, "Set Timeout to blocking");
94 #endif /* TEST_FAPI_ASYNC */
95
96 r = Fapi_CreateSeal_Async(context, path, type, size, policyPath,
97 authValue, data);
98 return_if_error_reset_state(r, "CreateSeal");
99
100 do {
101 /* We wait for file I/O to be ready if the FAPI state automata
102 are in a file I/O state. */
103 r = ifapi_io_poll(&context->io);
104 return_if_error(r, "Something went wrong with IO polling");
105
106 /* Repeatedly call the finish function, until FAPI has transitioned
107 through all execution stages / states of this invocation. */
108 r = Fapi_CreateSeal_Finish(context);
109 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
110
111 /* Reset the ESYS timeout to non-blocking, immediate response. */
112 r2 = Esys_SetTimeout(context->esys, 0);
113 return_if_error(r2, "Set Timeout to non-blocking");
114
115 return_if_error_reset_state(r, "CreateSeal");
116
117 LOG_TRACE("finished");
118 return TSS2_RC_SUCCESS;
119 }
120
121 /** Asynchronous function for Fapi_CreateSeal
122 *
123 * Creates a sealed object and stores it in the FAPI metadata store. If no data
124 * is provided, the TPM generates random data to fill the sealed object.
125 *
126 * Call Fapi_CreateSeal_Finish to finish the execution of this command.
127 *
128 * @param[in,out] context The FAPI_CONTEXT
129 * @param[in] path The path to the new sealed object
130 * @param[in] type The type of the new sealed object. May be NULL
131 * @param[in] size The size of the new sealed object. Must not be 0
132 * @param[in] policyPath The path to the policy that is associated with the new
133 * sealed object. May be NULL
134 * @param[in] authValue The authorization value for the new sealed object. May
135 * be NULL
136 * @param[in] data The data that is to be sealed within the new object. May be
137 * NULL
138 *
139 * @retval TSS2_RC_SUCCESS: if the function call was a success.
140 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, or path is NULL.
141 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
142 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if the parent key does not map to a
143 * FAPI key.
144 * @retval TSS2_FAPI_RC_BAD_PATH: if policyPath is non-NULL and does not map to
145 * a FAPI key.
146 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a sealed object already exists
147 * at path.
148 * @retval TSS2_FAPI_RC_BAD_VALUE: if the keyType is invalid.
149 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
150 * operation already pending.
151 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
152 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
153 * internal operations or return parameters.
154 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
155 * config file.
156 */
157 TSS2_RC
158 Fapi_CreateSeal_Async(
159 FAPI_CONTEXT *context,
160 char const *path,
161 char const *type,
162 size_t size,
163 char const *policyPath,
164 char const *authValue,
165 uint8_t const *data)
166 {
167 LOG_TRACE("called for context:%p", context);
168 LOG_TRACE("path: %s", path);
169 LOG_TRACE("type: %s", type);
170 LOG_TRACE("size: %zi", size);
171 LOG_TRACE("policyPath: %s", policyPath);
172 LOG_TRACE("authValue: %s", authValue);
173
174 TSS2_RC r;
175
176 /* Check for NULL parameters */
177 check_not_null(context);
178 check_not_null(path);
179
180 /* Reset all context-internal session state information. */
181 r = ifapi_session_init(context);
182 return_if_error(r, "Initialize CreateSeal");
183
184 /* Copy parameters to context for use during _Finish. */
185 memset(&context->cmd.Key_Create.public_templ, 0, sizeof(IFAPI_KEY_TEMPLATE));
186 r = ifapi_key_create_prepare_sensitive(context, path, policyPath, size,
187 authValue, data);
188 return_if_error(r, "Key create.");
189
190 /* Set the flags of the NV index to be created. If no type is given the empty-string
191 default type flags are set. */
192 r = ifapi_set_key_flags(type ? type : "",
193 (policyPath && strcmp(policyPath, "") != 0) ? true : false,
194 &context->cmd.Key_Create.public_templ);
195 return_if_error(r, "Set key flags for key");
196
197 context->cmd.Key_Create.public_templ.public.publicArea.objectAttributes &=
198 ~TPMA_OBJECT_SENSITIVEDATAORIGIN;
199
200 /* Initialize the context state for this operation. */
201 context->state = CREATE_SEAL;
202
203 LOG_TRACE("finished");
204 return TSS2_RC_SUCCESS;
205 }
206
207 /** Asynchronous finish function for Fapi_CreateSeal
208 *
209 * This function should be called after a previous Fapi_CreateSeal.
210 *
211 * @param[in,out] context The FAPI_CONTEXT
212 *
213 * @retval TSS2_RC_SUCCESS: if the function call was a success.
214 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
215 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
216 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
217 * operation already pending.
218 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
219 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
220 * internal operations or return parameters.
221 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
222 * complete. Call this function again later.
223 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
224 * the function.
225 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
226 * is not set.
227 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
228 */
229 TSS2_RC
230 Fapi_CreateSeal_Finish(
231 FAPI_CONTEXT *context)
232 {
233 LOG_TRACE("called for context:%p", context);
234
235 TSS2_RC r;
236
237 /* Check for NULL parameters */
238 check_not_null(context);
239
240 switch (context->state) {
241 statecase(context->state, CREATE_SEAL);
242 /* Create the seal object. A seal object internally is a so-called
243 KEYED_HASH object and created in the same way as a regular key.
244 Thus the function name ifapi_key_create(). */
245 r = ifapi_key_create(context, &context->cmd.Key_Create.public_templ);
246 return_try_again(r);
247 goto_if_error(r, "Key create", error_cleanup);
248 break;
249
250 statecasedefault(context->state);
251 }
252
253 error_cleanup:
254 /* Cleanup any intermediate results and state stored in the context. */
255 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
256 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
257 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
258 context->state = _FAPI_STATE_INIT;
259 LOG_TRACE("finished");
260 return r;
261 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #include "fapi_crypto.h"
21 #include "fapi_policy.h"
22 #include "ifapi_policyutil_execute.h"
23 #include "ifapi_json_deserialize.h"
24 #define LOGMODULE fapi
25 #include "util/log.h"
26 #include "util/aux_util.h"
27
28 /** One-Call function for Fapi_Decrypt
29 *
30 * Decrypts data that was previously encrypted with Fapi_Encrypt.
31 *
32 * @param[in,out] context The FAPI_CONTEXT
33 * @param[in] keyPath The decryption key.
34 * @param[in] cipherText The ciphertext to decrypt.
35 * @param[in] cipherTextSize The size of the ciphertext to decrypt.
36 * @param[out] plainText the decrypted ciphertext. May be NULL
37 * (callee-allocated)
38 * @param[out] plainTextSize The size of the ciphertext in bytes. May be NULL
39 *
40 * @retval TSS2_RC_SUCCESS: if the function call was a success.
41 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or cipherText is NULL.
42 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
43 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if can’t find the key necessary to decrypt
44 * the file.
45 * @retval TSS2_FAPI_RC_BAD_KEY: if the decryption key is unsuitable for the
46 * requested operation.
47 * @retval TSS2_FAPI_RC_BAD_VALUE: if the decryption fails
48 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
49 * operation already pending.
50 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
51 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
52 * internal operations or return parameters.
53 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
54 * config file.
55 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
56 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
57 * this function needs to be called again.
58 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
59 * during authorization.
60 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
61 * is not set.
62 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
63 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
64 * was not successful.
65 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
66 */
67 TSS2_RC
68 Fapi_Decrypt(
69 FAPI_CONTEXT *context,
70 char const *keyPath,
71 uint8_t const *cipherText,
72 size_t cipherTextSize,
73 uint8_t **plainText,
74 size_t *plainTextSize)
75 {
76 LOG_TRACE("called for context:%p", context);
77
78 TSS2_RC r, r2;
79
80 /* Check for NULL parameters */
81 check_not_null(context);
82 check_not_null(keyPath);
83 check_not_null(cipherText);
84
85 /* Check whether TCTI and ESYS are initialized */
86 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
87 TSS2_FAPI_RC_NO_TPM);
88
89 /* If the async state automata of FAPI shall be tested, then we must not set
90 the timeouts of ESYS to blocking mode.
91 During testing, the mssim tcti will ensure multiple re-invocations.
92 Usually however the synchronous invocations of FAPI shall instruct ESYS
93 to block until a result is available. */
94 #ifndef TEST_FAPI_ASYNC
95 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
96 return_if_error_reset_state(r, "Set Timeout to blocking");
97 #endif /* TEST_FAPI_ASYNC */
98
99 r = Fapi_Decrypt_Async(context, keyPath, cipherText, cipherTextSize);
100 return_if_error_reset_state(r, "Data_Encrypt");
101
102 do {
103 /* We wait for file I/O to be ready if the FAPI state automata
104 are in a file I/O state. */
105 r = ifapi_io_poll(&context->io);
106 return_if_error(r, "Something went wrong with IO polling");
107
108 /* Repeatedly call the finish function, until FAPI has transitioned
109 through all execution stages / states of this invocation. */
110 r = Fapi_Decrypt_Finish(context, plainText, plainTextSize);
111 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
112
113 /* Reset the ESYS timeout to non-blocking, immediate response. */
114 r2 = Esys_SetTimeout(context->esys, 0);
115 return_if_error(r2, "Set Timeout to non-blocking");
116
117 return_if_error_reset_state(r, "Data_Decrypt");
118
119 LOG_TRACE("finished");
120 return TSS2_RC_SUCCESS;
121 }
122
123 /** Asynchronous function for Fapi_Decrypt
124 *
125 * Decrypts data that was previously encrypted with Fapi_Encrypt.
126 *
127 * Call Fapi_Decrypt_Finish to finish the execution of this command.
128 *
129 * @param[in,out] context The FAPI_CONTEXT
130 * @param[in] keyPath The decryption key.
131 * @param[in] cipherText The ciphertext to decrypt
132 * @param[in] cipherTextSize The size of the ciphertext to decrypt
133 *
134 * @retval TSS2_RC_SUCCESS: if the function call was a success.
135 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or cipherText is NULL.
136 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
137 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if can’t find the key necessary to decrypt
138 * the file.
139 * @retval TSS2_FAPI_RC_BAD_KEY: if the decryption key is unsuitable for the
140 * requested operation.
141 * @retval TSS2_FAPI_RC_BAD_VALUE: if the decryption fails
142 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
143 * operation already pending.
144 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
145 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
146 * internal operations or return parameters.
147 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
148 * config file.
149 */
150 TSS2_RC
151 Fapi_Decrypt_Async(
152 FAPI_CONTEXT *context,
153 char const *keyPath,
154 uint8_t const *cipherText,
155 size_t cipherTextSize)
156 {
157 LOG_TRACE("called for context:%p", context);
158 LOG_TRACE("cipherText: %s", cipherText);
159
160 TSS2_RC r;
161
162 /* Check for NULL parameters */
163 check_not_null(context);
164 check_not_null(keyPath);
165 check_not_null(cipherText);
166
167 /* Helpful alias pointers */
168 IFAPI_Data_EncryptDecrypt * command = &(context->cmd.Data_EncryptDecrypt);
169
170 /* Reset all context-internal session state information. */
171 r = ifapi_session_init(context);
172 return_if_error(r, "Initialize Decrypt");
173
174 command->object_handle = ESYS_TR_NONE;
175
176 goto_if_error(r, "Invalid cipher object.", error_cleanup);
177
178 /* Copy parameters to context for use during _Finish. */
179 uint8_t *inData = malloc(cipherTextSize);
180 goto_if_null(inData, "Out of memory", r, error_cleanup);
181 memcpy(inData, cipherText, cipherTextSize);
182 command->in_data = inData;
183 command->numBytes = cipherTextSize;
184 strdup_check(command->keyPath, keyPath, r, error_cleanup);
185
186 /* Initialize the context state for this operation. */
187 context->state = DATA_DECRYPT_WAIT_FOR_PROFILE;
188
189 LOG_TRACE("finished");
190 return r;
191
192 error_cleanup:
193 SAFE_FREE(command->in_data);
194 SAFE_FREE(command->keyPath);
195 return r;
196 }
197
198 /** Asynchronous finish function for Fapi_Decrypt
199 *
200 * This function should be called after a previous Fapi_Decrypt.
201 *
202 * @param[in,out] context The FAPI_CONTEXT
203 * @param[out] plainText the decrypted ciphertext. May be NULL
204 * (callee-allocated)
205 * @param[out] plainTextSize The size of the ciphertext in bytes. May be NULL
206 *
207 * @retval TSS2_RC_SUCCESS: if the function call was a success.
208 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, plainText or plainTextSize
209 * is NULL.
210 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
211 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
212 * operation already pending.
213 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
214 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
215 * internal operations or return parameters.
216 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
217 * complete. Call this function again later.
218 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
219 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
220 * the function.
221 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
222 * during authorization.
223 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
224 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
225 * is not set.
226 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
227 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
228 * was not successful.
229 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
230 */
231 TSS2_RC
232 Fapi_Decrypt_Finish(
233 FAPI_CONTEXT *context,
234 uint8_t **plainText,
235 size_t *plainTextSize)
236 {
237 LOG_TRACE("called for context:%p", context);
238
239 TSS2_RC r;
240 TPM2B_PUBLIC_KEY_RSA *tpmPlainText = NULL;
241
242 /* Check for NULL parameters */
243 check_not_null(context);
244
245 /* Helpful alias pointers */
246 IFAPI_OBJECT *encKeyObject = NULL;
247 IFAPI_Data_EncryptDecrypt * command = &(context->cmd.Data_EncryptDecrypt);
248
249 switch (context->state) {
250 statecase(context->state, DATA_DECRYPT_WAIT_FOR_PROFILE);
251 /* Retrieve the profile for the provided key in order to get the
252 encryption scheme below. */
253 r = ifapi_profiles_get(&context->profiles, command->keyPath,
254 &command->profile);
255 return_try_again(r);
256 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
257
258 /* Initialize a session used for authorization and parameter encryption. */
259 r = ifapi_get_sessions_async(context,
260 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
261 TPMA_SESSION_ENCRYPT | TPMA_SESSION_DECRYPT, 0);
262 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
263
264 fallthrough;
265
266 statecase(context->state, DATA_DECRYPT_WAIT_FOR_SESSION);
267 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
268 context->profiles.default_profile.nameAlg);
269 return_try_again(r);
270 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
271
272 /* Load the key used for decryption. */
273 r = ifapi_load_keys_async(context, command->keyPath);
274 return_try_again(r);
275 goto_if_error(r, "Load keys.", error_cleanup);
276
277 fallthrough;
278
279 statecase(context->state, DATA_DECRYPT_WAIT_FOR_KEY);
280 r = ifapi_load_keys_finish(context, IFAPI_FLUSH_PARENT,
281 &command->key_handle,
282 &command->key_object);
283 return_try_again(r);
284 goto_if_error_reset_state(r, " Load key.", error_cleanup);
285
286 encKeyObject = command->key_object;
287
288 if (encKeyObject->misc.key.public.publicArea.type != TPM2_ALG_RSA &&
289 encKeyObject->misc.key.public.publicArea.type != TPM2_ALG_ECC) {
290 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid algorithm", error_cleanup);
291 }
292 fallthrough;
293
294 statecase(context->state, DATA_DECRYPT_AUTHORIZE_KEY);
295 /* Authorize for the key with password or policy. */
296 r = ifapi_authorize_object(context, command->key_object, &command->auth_session);
297 return_try_again(r);
298 goto_if_error(r, "Authorize key.", error_cleanup);
299 TPM2B_DATA null_data = {.size = 0, .buffer = {} };
300
301 /* Copy cipher data to tpm object */
302 TPM2B_PUBLIC_KEY_RSA *aux_data = (TPM2B_PUBLIC_KEY_RSA *)&context->aux_data;
303 aux_data->size = context->cmd.Data_EncryptDecrypt.numBytes;
304 memcpy(&aux_data->buffer[0], context->cmd.Data_EncryptDecrypt.in_data,
305 aux_data->size);
306
307 /* Decrypt the actual data. */
308 r = Esys_RSA_Decrypt_Async(context->esys,
309 context->cmd.Data_EncryptDecrypt.key_handle,
310 command->auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
311 aux_data,
312 &command->profile->rsa_decrypt_scheme,
313 &null_data);
314 goto_if_error(r, "Error esys rsa decrypt", error_cleanup);
315
316 fallthrough;
317
318 statecase(context->state, DATA_DECRYPT_WAIT_FOR_RSA_DECRYPTION);
319 r = Esys_RSA_Decrypt_Finish(context->esys, &tpmPlainText);
320 return_try_again(r);
321 goto_if_error_reset_state(r, "RSA decryption.", error_cleanup);
322
323 /* Duplicate the decrypted plaintext for returning to the user. */
324 if (plainTextSize)
325 *plainTextSize = tpmPlainText->size;
326 if (plainText) {
327 *plainText = malloc(tpmPlainText->size);
328 goto_if_null(*plainText, "Out of memory", TSS2_FAPI_RC_MEMORY, error_cleanup);
329
330 memcpy(*plainText, &tpmPlainText->buffer[0], tpmPlainText->size);
331 SAFE_FREE(tpmPlainText);
332 }
333
334 /* Flush the used key. */
335 r = Esys_FlushContext_Async(context->esys,
336 command->key_handle);
337 goto_if_error(r, "Error: FlushContext", error_cleanup);
338
339 fallthrough;
340
341 statecase(context->state, DATA_DECRYPT_WAIT_FOR_FLUSH);
342 r = Esys_FlushContext_Finish(context->esys);
343 return_try_again(r);
344
345 goto_if_error(r, "Error: FlushContext", error_cleanup);
346 command->key_handle = ESYS_TR_NONE;
347 fallthrough;
348
349 statecase(context->state, DATA_DECRYPT_CLEANUP)
350 /* Cleanup session. */
351 r = ifapi_cleanup_session(context);
352 try_again_or_error_goto(r, "Cleanup", error_cleanup);
353
354 break;
355
356 statecasedefault(context->state);
357 }
358
359 context->state = _FAPI_STATE_INIT;
360
361 /* Cleanup of local objects */
362 SAFE_FREE(tpmPlainText);
363
364 /* Cleanup of command related objects */
365 ifapi_cleanup_ifapi_object(command->key_object);
366 SAFE_FREE(command->keyPath);
367 SAFE_FREE(command->in_data);
368
369 /* Cleanup of context related objects */
370 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
371 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
372
373 LOG_TRACE("finished");
374 return TSS2_RC_SUCCESS;
375
376 error_cleanup:
377 /* Cleanup of local objects */
378 SAFE_FREE(tpmPlainText);
379
380 /* Cleanup of command related objects */
381 ifapi_cleanup_ifapi_object(command->key_object);
382 SAFE_FREE(command->keyPath);
383 SAFE_FREE(command->in_data);
384
385 /* Cleanup of context related objects */
386 if (command->key_handle != ESYS_TR_NONE)
387 Esys_FlushContext(context->esys, command->key_handle);
388 ifapi_session_clean(context);
389 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
390 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
391 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
392
393 return r;
394 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "tss2_fapi.h"
16 #include "fapi_int.h"
17 #include "fapi_util.h"
18 #include "tss2_esys.h"
19 #include "ifapi_json_serialize.h"
20 #include "ifapi_json_deserialize.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25
26 /** One-Call function for Fapi_Delete
27 *
28 * Deletes a given key, policy or NV index from the system.
29 *
30 * @param[in,out] context The ESAPI_CONTEXT
31 * @param[in] path The path to the entity that is to be deleted
32 *
33 * @retval TSS2_RC_SUCCESS: if the function call was a success.
34 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
35 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
36 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
37 * @retval TSS2_FAPI_RC_NOT_DELETABLE: if the entity is not deletable or the
38 * path is read-only.
39 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
40 * operation already pending.
41 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
42 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
43 * internal operations or return parameters.
44 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
45 * config file.
46 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
47 * during authorization.
48 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
49 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
50 * the function.
51 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
52 * this function needs to be called again.
53 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
54 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
55 * is not set.
56 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
57 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
58 * was not successful.
59 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
60 */
61 TSS2_RC
62 Fapi_Delete(
63 FAPI_CONTEXT *context,
64 char const *path)
65 {
66 LOG_TRACE("called for context:%p", context);
67
68 TSS2_RC r;
69
70 /* Check for NULL parameters */
71 check_not_null(context);
72 check_not_null(path);
73
74 r = Fapi_Delete_Async(context, path);
75 return_if_error_reset_state(r, "Entity_Delete");
76
77 do {
78 /* We wait for file I/O to be ready if the FAPI state automata
79 are in a file I/O state. */
80 r = ifapi_io_poll(&context->io);
81 return_if_error(r, "Something went wrong with IO polling");
82
83 /* Repeatedly call the finish function, until FAPI has transitioned
84 through all execution stages / states of this invocation. */
85 r = Fapi_Delete_Finish(context);
86 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
87
88 return_if_error_reset_state(r, "Entity_Delete");
89
90 return TSS2_RC_SUCCESS;
91 }
92
93 /** Asynchronous function for Fapi_Delete
94 *
95 * Deletes a given key, policy or NV index from the system.
96
97 * Call Fapi_Delete_Finish to finish the execution of this command.
98 *
99 * @param[in,out] context The ESAPI_CONTEXT
100 * @param[in] path The path to the entity that is to be deleted
101 *
102 * @retval TSS2_RC_SUCCESS: if the function call was a success.
103 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
104 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
105 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
106 * @retval TSS2_FAPI_RC_NOT_DELETABLE: if the entity is not deletable or the
107 * path is read-only.
108 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
109 * operation already pending.
110 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
111 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
112 * internal operations or return parameters.
113 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
114 * config file.
115 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
116 * during authorization.
117 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
118 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
119 * the function.
120 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
121 */
122 TSS2_RC
123 Fapi_Delete_Async(
124 FAPI_CONTEXT *context,
125 char const *path)
126 {
127 LOG_TRACE("called for context:%p", context);
128 LOG_TRACE("path: %s", path);
129
130 TSS2_RC r;
131
132 /* Check for NULL parameters */
133 check_not_null(context);
134 check_not_null(path);
135
136 /* Helpful alias pointers */
137 IFAPI_Entity_Delete * command = &(context->cmd.Entity_Delete);
138 IFAPI_OBJECT *object = &command->object;
139 IFAPI_OBJECT *authObject = &command->auth_object;
140
141 /* Copy parameters to context for use during _Finish. */
142 strdup_check(command->path, path, r, error_cleanup);
143
144 /* List all keystore elements in the path hierarchy of the provided
145 path. The last of these is the object to be deleted. */
146 r = ifapi_keystore_list_all(&context->keystore, path, &command->pathlist,
147 &command->numPaths);
148 return_if_error(r, "get entities.");
149
150 command->path_idx = command->numPaths;
151
152 if (command->numPaths == 0) {
153 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "No objects found.", error_cleanup);
154 }
155
156 object->objectType = IFAPI_OBJ_NONE;
157 authObject->objectType = IFAPI_OBJ_NONE;
158
159 if (ifapi_path_type_p(path, IFAPI_EXT_PATH) ||
160 (ifapi_path_type_p(path, IFAPI_POLICY_PATH))) {
161 /* No session will be needed these files can be deleted without
162 interaction with the TPM */
163 r = ifapi_non_tpm_mode_init(context);
164 return_if_error(r, "Initialize Entity_Delete");
165
166 context->state = ENTITY_DELETE_GET_FILE;
167 } else {
168 /* Check whether TCTI and ESYS are initialized */
169 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
170 TSS2_FAPI_RC_NO_TPM);
171
172 /* If the async state automata of FAPI shall be tested, then we must not set
173 the timeouts of ESYS to blocking mode.
174 During testing, the mssim tcti will ensure multiple re-invocations.
175 Usually however the synchronous invocations of FAPI shall instruct ESYS
176 to block until a result is available. */
177 #ifndef TEST_FAPI_ASYNC
178 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
179 return_if_error_reset_state(r, "Set Timeout to blocking");
180 #endif /* TEST_FAPI_ASYNC */
181
182 /* A TPM session will be created to enable object authorization */
183 r = ifapi_session_init(context);
184 return_if_error(r, "Initialize Entity_Delete");
185
186 r = ifapi_get_sessions_async(context,
187 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
188 0, 0);
189 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
190
191 context->state = ENTITY_DELETE_WAIT_FOR_SESSION;
192 }
193
194 LOG_TRACE("finished");
195 return TSS2_RC_SUCCESS;
196
197 error_cleanup:
198 /* Cleanup any intermediate results and state stored in the context. */
199 SAFE_FREE(command->path);
200 if (Esys_FlushContext(context->esys, context->session1) != TSS2_RC_SUCCESS) {
201 LOG_ERROR("Cleanup session failed.");
202 }
203 return r;
204 }
205
206
207 /** Asynchronous finish function for Fapi_Delete
208 *
209 * This function should be called after a previous Fapi_Delete_Async.
210 *
211 * @param[in,out] context The FAPI_CONTEXT
212 *
213 * @retval TSS2_RC_SUCCESS: if the function call was a success.
214 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
215 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
216 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
217 * operation already pending.
218 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
219 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
220 * internal operations or return parameters.
221 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
222 * complete. Call this function again later.
223 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
224 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
225 * the function.
226 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
227 * during authorization.
228 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
229 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
230 * is not set.
231 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
232 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
233 * was not successful.
234 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
235 */
236 TSS2_RC
237 Fapi_Delete_Finish(
238 FAPI_CONTEXT *context)
239 {
240 LOG_TRACE("called for context:%p", context);
241
242 TSS2_RC r;
243 ESYS_TR authIndex;
244 ESYS_TR auth_session;
245 char *path;
246
247 /* Check for NULL parameters */
248 check_not_null(context);
249
250 /* Helpful alias pointers */
251 IFAPI_Entity_Delete * command = &(context->cmd.Entity_Delete);
252 IFAPI_OBJECT *object = &command->object;
253 IFAPI_OBJECT *authObject = &command->auth_object;
254
255 switch (context->state) {
256 statecase(context->state, ENTITY_DELETE_WAIT_FOR_SESSION);
257 /* If a TPM object (e.g. a persistent key) was referenced, then this
258 is the entry point. */
259 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
260 context->profiles.default_profile.nameAlg);
261 return_try_again(r);
262 goto_if_error(r, "Create FAPI session.", error_cleanup);
263
264 fallthrough;
265
266 statecase(context->state, ENTITY_DELETE_GET_FILE);
267 /* If a non-TPM object (e.g. a policy) was referenced, then this is the
268 entry point. */
269 /* Use last path in the path list */
270 command->path_idx -= 1;
271 path = command->pathlist[command->path_idx];
272 LOG_TRACE("Delete object: %s %zu", path, command->path_idx);
273
274 if (ifapi_path_type_p(path, IFAPI_EXT_PATH)) {
275 /* External keyfile can be deleted directly without TPM operations. */
276 context->state = ENTITY_DELETE_FILE;
277 return TSS2_FAPI_RC_TRY_AGAIN;
278 }
279
280 if (ifapi_path_type_p(path, IFAPI_POLICY_PATH)) {
281 /* Policy file can be deleted directly without TPM operations. */
282 context->state = ENTITY_DELETE_POLICY;
283 return TSS2_FAPI_RC_TRY_AGAIN;
284 }
285
286 /* Load the object metadata from the keystore. */
287 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
288 return_if_error2(r, "Could not open: %s", path);
289
290 fallthrough;
291
292 statecase(context->state, ENTITY_DELETE_READ);
293 /* We only end up in this path, if the referenced object requires
294 TPM operations; e.g. persistent key or NV index. */
295 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
296 return_try_again(r);
297 return_if_error_reset_state(r, "read_finish failed");
298
299 /* Initialize the ESYS object for the persistent key or NV Index. */
300 r = ifapi_initialize_object(context->esys, object);
301 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
302
303 if (object->objectType == IFAPI_KEY_OBJ) {
304 /* If the object is a key, we jump over to ENTITY_DELETE_KEY. */
305 command->is_key = true;
306 context->state = ENTITY_DELETE_KEY;
307 return TSS2_FAPI_RC_TRY_AGAIN;
308
309 } else if (object->objectType == IFAPI_NV_OBJ) {
310 /* Prepare for the deletion of an NV index. */
311 command->is_key = false;
312
313 if (object->misc.nv.hierarchy == ESYS_TR_RH_OWNER) {
314 authIndex = ESYS_TR_RH_OWNER;
315 ifapi_init_hierarchy_object(authObject, authIndex);
316 } else {
317 *authObject = *object;
318 authIndex = object->handle;
319 }
320 command->auth_index = authIndex;
321 context->state = ENTITY_DELETE_AUTHORIZE_NV;
322 } else {
323 context->state = ENTITY_DELETE_FILE;
324 return TSS2_FAPI_RC_TRY_AGAIN;
325 }
326 fallthrough;
327
328 statecase(context->state, ENTITY_DELETE_AUTHORIZE_NV);
329 /* Authorize with the storage hierarhcy / "owner" to delete the NV index. */
330 r = ifapi_authorize_object(context, authObject, &auth_session);
331 return_try_again(r);
332 goto_if_error(r, "Authorize NV object.", error_cleanup);
333
334 /* Delete the NV index. */
335 r = Esys_NV_UndefineSpace_Async(context->esys,
336 command->auth_index,
337 object->handle,
338 auth_session,
339 ESYS_TR_NONE,
340 ESYS_TR_NONE);
341 goto_if_error_reset_state(r, " Fapi_NV_UndefineSpace_Async", error_cleanup);
342
343 context->state = ENTITY_DELETE_NULL_AUTH_SENT_FOR_NV;
344 return TSS2_FAPI_RC_TRY_AGAIN;
345
346 statecase(context->state, ENTITY_DELETE_KEY);
347 if (object->misc.key.persistent_handle) {
348 /* Delete the persistent handle from the TPM. */
349 r = Esys_EvictControl_Async(context->esys, ESYS_TR_RH_OWNER,
350 object->handle,
351 context->session1,
352 ESYS_TR_NONE, ESYS_TR_NONE,
353 object->misc.key.persistent_handle);
354 goto_if_error(r, "Evict Control", error_cleanup);
355 context->state = ENTITY_DELETE_NULL_AUTH_SENT_FOR_KEY;
356 } else {
357 context->state = ENTITY_DELETE_FILE;
358 return TSS2_FAPI_RC_TRY_AGAIN;
359 }
360 fallthrough;
361
362 statecase(context->state, ENTITY_DELETE_AUTH_SENT_FOR_KEY);
363 fallthrough;
364 statecase(context->state, ENTITY_DELETE_NULL_AUTH_SENT_FOR_KEY);
365 r = Esys_EvictControl_Finish(context->esys,
366 &command->new_object_handle);
367 return_try_again(r);
368 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH) {
369 /* If evict control failed, we know that an owner password was set
370 and we need to re-issue the command with a password being set. */
371 if (context->state == ENTITY_DELETE_NULL_AUTH_SENT_FOR_KEY) {
372 ifapi_init_hierarchy_object(authObject,
373 TPM2_RH_OWNER);
374 r = ifapi_set_auth(context, authObject,
375 "Owner Authorization");
376 goto_if_error_reset_state(r, "Set owner authorization", error_cleanup);
377
378 context->state = ENTITY_DELETE_AUTH_SENT_FOR_KEY;
379 return TSS2_FAPI_RC_TRY_AGAIN;
380 }
381 }
382 goto_if_error_reset_state(r, "FAPI Entity_Delete", error_cleanup);
383
384 context->state = ENTITY_DELETE_FILE;
385 return TSS2_FAPI_RC_TRY_AGAIN;
386 break;
387
388 statecase(context->state, ENTITY_DELETE_AUTH_SENT_FOR_NV);
389 fallthrough;
390 statecase(context->state, ENTITY_DELETE_NULL_AUTH_SENT_FOR_NV);
391 r = Esys_NV_UndefineSpace_Finish(context->esys);
392 return_try_again(r);
393
394 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH) {
395 /* If undefine space failed, we know that an owner password was set
396 and we need to re-issue the command with a password being set. */
397 if (context->state == ENTITY_DELETE_NULL_AUTH_SENT_FOR_NV) {
398 r = ifapi_set_auth(context, authObject, "Entity Delete object");
399 goto_if_error_reset_state(r, " Fapi_NV_UndefineSpace", error_cleanup);
400
401 r = Esys_NV_UndefineSpace_Async(context->esys,
402 command->auth_index,
403 object->handle,
404 context->session1,
405 context->session2,
406 ESYS_TR_NONE);
407 goto_if_error_reset_state(r, "FAPI Entity_Delete", error_cleanup);
408
409 context->state = ENTITY_DELETE_AUTH_SENT_FOR_NV;
410 return TSS2_FAPI_RC_TRY_AGAIN;
411 }
412 }
413 goto_if_error_reset_state(r, "FAPI NV_UndefineSpace", error_cleanup);
414
415 LOG_TRACE("NV Object undefined.");
416 context->state = ENTITY_DELETE_FILE;
417 return TSS2_FAPI_RC_TRY_AGAIN;
418 break;
419
420 statecase(context->state, ENTITY_DELETE_POLICY);
421 /* This is the simple case of deleting a policy from the keystore. */
422 path = command->pathlist[command->path_idx];
423 LOG_TRACE("Delete: %s", path);
424
425 r = ifapi_policy_delete(&context->pstore, path);
426 goto_if_error_reset_state(r, "Could not delete: %s", error_cleanup, path);
427
428 if (command->path_idx > 0)
429 context->state = ENTITY_DELETE_GET_FILE;
430 else
431 context->state = ENTITY_DELETE_REMOVE_DIRS;
432 return TSS2_FAPI_RC_TRY_AGAIN;
433
434 statecase(context->state, ENTITY_DELETE_FILE);
435 /* This is the simple case of deleting an external (pub)key from the keystore
436 or we enter here after the TPM operation for the persistent key or NV index
437 deletion have been performed. */
438 path = command->pathlist[command->path_idx];
439 LOG_TRACE("Delete: %s", path);
440 ifapi_cleanup_ifapi_object(object);
441 ifapi_cleanup_ifapi_object(authObject);
442
443 /* Delete all the object's data from the keystore. */
444 r = ifapi_keystore_delete(&context->keystore, path);
445 goto_if_error_reset_state(r, "Could not delete: %s", error_cleanup, path);
446
447 if (command->path_idx > 0) {
448 context->state = ENTITY_DELETE_GET_FILE;
449 return TSS2_FAPI_RC_TRY_AGAIN;
450 }
451
452 fallthrough;
453
454 statecase(context->state, ENTITY_DELETE_REMOVE_DIRS);
455 /* For some cases, we need to remove the directory that contained the
456 meta data as well. */
457 r = ifapi_keystore_remove_directories(&context->keystore, command->path);
458 goto_if_error(r, "Error while removing directories", error_cleanup);
459
460 context->state = _FAPI_STATE_INIT;
461
462 LOG_DEBUG("success");
463 r = TSS2_RC_SUCCESS;
464 break;
465
466 statecasedefault(context->state);
467 }
468
469 /* Reset the ESYS timeout to non-blocking, immediate response. */
470 if (context->esys) {
471 r = Esys_SetTimeout(context->esys, 0);
472 goto_if_error(r, "Set Timeout to non-blocking", error_cleanup);
473 }
474
475 /* Cleanup intermediate state stored in the context. */
476 SAFE_FREE(command->path);
477 ifapi_cleanup_ifapi_object(authObject);
478 ifapi_cleanup_ifapi_object(object);
479 for (size_t i = 0; i < command->numPaths; i++) {
480 SAFE_FREE(command->pathlist[i]);
481 }
482 SAFE_FREE(command->pathlist);
483 ifapi_session_clean(context);
484 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
485 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
486 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
487
488 LOG_TRACE("finished");
489 return r;
490
491 error_cleanup:
492 /* Cleanup any intermediate results and state stored in the context. */
493 Esys_SetTimeout(context->esys, 0);
494 ifapi_cleanup_ifapi_object(object);
495 SAFE_FREE(command->path);
496 for (size_t i = 0; i < command->numPaths; i++) {
497 SAFE_FREE(command->pathlist[i]);
498 }
499 SAFE_FREE(command->pathlist);
500 ifapi_session_clean(context);
501 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
502 return r;
503 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #include "ifapi_json_serialize.h"
21 #include "fapi_policy.h"
22 #define LOGMODULE fapi
23 #include "util/log.h"
24 #include "util/aux_util.h"
25 #include "fapi_crypto.h"
26
27 #define IV_SIZE 16
28
29 /** One-Call function for Fapi_Encrypt
30 *
31 * Encrypt the provided data for the target key using the TPM encryption
32 * schemes as specified in the crypto profile.
33 * This function does not use the TPM; i.e. works in non-TPM mode.
34 *
35 * @param[in,out] context The FAPI_CONTEXT
36 * @param[in] keyPath THe path to the encryption key
37 * @param[in] plainText The plaintext data to encrypt
38 * @param[in] plainTextSize The size of the plainText in bytes
39 * @param[out] cipherText The encoded cipher text.
40 * @param[out] cipherTextSize The size of the encoded cipher text.
41 *
42 * @retval TSS2_RC_SUCCESS: if the function call was a success.
43 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, keyPath, plainText, or
44 * cipherText is NULL.
45 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
46 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if keyPath does not map to a FAPI key.
47 * @retval TSS2_FAPI_RC_BAD_KEY: if the key at keyPath is unsuitable for
48 * encryption.
49 * @retval TSS2_FAPI_RC_BAD_VALUE: if plainTextSize is 0.
50 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
51 * operation already pending.
52 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
53 * internal operations or return parameters.
54 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
55 * config file.
56 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
57 * object store.
58 * @retval TSS2_FAPI_RC_NOT_IMPLEMENTED if the encryption algorithm is not available.
59 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
60 * this function needs to be called again.
61 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
62 * during authorization.
63 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
64 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
65 * is not set.
66 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
67 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
68 * was not successful.
69 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
70 */
71 TSS2_RC
72 Fapi_Encrypt(
73 FAPI_CONTEXT *context,
74 char const *keyPath,
75 uint8_t const *plainText,
76 size_t plainTextSize,
77 uint8_t **cipherText,
78 size_t *cipherTextSize)
79 {
80 LOG_TRACE("called for context:%p", context);
81
82 TSS2_RC r, r2;
83
84 /* Check for NULL parameters */
85 check_not_null(context);
86 check_not_null(keyPath);
87 check_not_null(plainText);
88 check_not_null(cipherText);
89
90 /* Check whether TCTI and ESYS are initialized */
91 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
92 TSS2_FAPI_RC_NO_TPM);
93
94 /* If the async state automata of FAPI shall be tested, then we must not set
95 the timeouts of ESYS to blocking mode.
96 During testing, the mssim tcti will ensure multiple re-invocations.
97 Usually however the synchronous invocations of FAPI shall instruct ESYS
98 to block until a result is available. */
99 #ifndef TEST_FAPI_ASYNC
100 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
101 return_if_error_reset_state(r, "Set Timeout to blocking");
102 #endif /* TEST_FAPI_ASYNC */
103
104 r = Fapi_Encrypt_Async(context, keyPath, plainText, plainTextSize);
105 return_if_error_reset_state(r, "Data_Encrypt");
106
107 do {
108 /* We wait for file I/O to be ready if the FAPI state automata
109 are in a file I/O state. */
110 r = ifapi_io_poll(&context->io);
111 return_if_error(r, "Something went wrong with IO polling");
112
113 /* Repeatedly call the finish function, until FAPI has transitioned
114 through all execution stages / states of this invocation. */
115 r = Fapi_Encrypt_Finish(context, cipherText, cipherTextSize);
116 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
117
118 /* Reset the ESYS timeout to non-blocking, immediate response. */
119 r2 = Esys_SetTimeout(context->esys, 0);
120 return_if_error(r2, "Set Timeout to non-blocking");
121
122 return_if_error_reset_state(r, "Data_Encrypt");
123
124 LOG_TRACE("finished");
125 return TSS2_RC_SUCCESS;
126 }
127
128 /** Asynchronous function for Fapi_Encrypt
129 *
130 * Encrypt the provided data for the target key using the TPM encryption
131 * schemes as specified in the crypto profile.
132 * This function does not use the TPM; i.e. works in non-TPM mode.
133 *
134 * Call Fapi_Encrypt_Finish to finish the execution of this command.
135 *
136 * @param[in,out] context The FAPI_CONTEXT
137 * @param[in] keyPath The path to the encryption key
138 * @param[in] plainText The plainText data to encrypt
139 * @param[in] plainTextSize The size of the plainText in bytes
140 *
141 * @retval TSS2_RC_SUCCESS: if the function call was a success.
142 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, keyPath or plainText is
143 * NULL.
144 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
145 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if keyPath does not map to a FAPI key.
146 * @retval TSS2_FAPI_RC_BAD_KEY: if the key at keyPath is unsuitable for
147 * encryption.
148 * @retval TSS2_FAPI_RC_BAD_VALUE: if plainTextSize is 0.
149 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
150 * operation already pending.
151 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
152 * internal operations or return parameters.
153 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
154 * config file.
155 */
156 TSS2_RC
157 Fapi_Encrypt_Async(
158 FAPI_CONTEXT *context,
159 char const *keyPath,
160 uint8_t const *plainText,
161 size_t plainTextSize)
162 {
163 LOG_TRACE("called for context:%p", context);
164 LOG_TRACE("keyPath: %s", keyPath);
165 if (plainText) {
166 LOGBLOB_TRACE(plainText, plainTextSize, "plainText");
167 } else {
168 LOG_TRACE("plainText: (null) plainTextSize: %zi", plainTextSize);
169 }
170
171 TSS2_RC r;
172
173 /* Check for NULL parameters */
174 check_not_null(context);
175 check_not_null(keyPath);
176 check_not_null(plainText);
177
178 /* Helpful alias pointers */
179 IFAPI_Data_EncryptDecrypt * command = &(context->cmd.Data_EncryptDecrypt);
180
181 r = ifapi_session_init(context);
182 return_if_error(r, "Initialize Encrypt");
183
184 /* Copy parameters to context for use during _Finish. */
185 uint8_t *inData = malloc(plainTextSize);
186 goto_if_null(inData, "Out of memory", r, error_cleanup);
187 memcpy(inData, plainText, plainTextSize);
188 command->in_data = inData;
189
190 strdup_check(command->keyPath, keyPath, r, error_cleanup);
191
192 command->in_dataSize = plainTextSize;
193 command->key_handle = ESYS_TR_NONE;
194
195 /* Initialize the context state for this operation. */
196 context->state = DATA_ENCRYPT_WAIT_FOR_PROFILE;
197 LOG_TRACE("finished");
198 return TSS2_RC_SUCCESS;
199
200 error_cleanup:
201 SAFE_FREE(inData);
202 SAFE_FREE(command->keyPath);
203 return r;
204 }
205
206 /** Asynchronous finish function for Fapi_Encrypt
207 *
208 * This function should be called after a previous Fapi_Encrypt_Async.
209 *
210 * @param[in,out] context The FAPI_CONTEXT
211 * @param[out] cipherText The encoded ciphertext
212 * @param[out] cipherTextSize The size of the encoded cipher text.
213 *
214 * @retval TSS2_RC_SUCCESS: if the function call was a success.
215 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or ciphertext is NULL.
216 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
217 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
218 * operation already pending.
219 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
220 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
221 * internal operations or return parameters.
222 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
223 * complete. Call this function again later.
224 * @retval TSS2_FAPI_RC_NOT_IMPLEMENTED if the encryption algorithm is not available.
225 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
226 * the function.
227 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
228 * during authorization.
229 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
230 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
231 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
232 * is not set.
233 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
234 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
235 * was not successful.
236 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
237 */
238 TSS2_RC
239 Fapi_Encrypt_Finish(
240 FAPI_CONTEXT *context,
241 uint8_t **cipherText,
242 size_t *cipherTextSize)
243 {
244 LOG_TRACE("called for context:%p", context);
245
246 TSS2_RC r;
247
248 /* Check for NULL parameters */
249 check_not_null(context);
250 check_not_null(cipherText);
251
252 /* Helpful alias pointers */
253 IFAPI_Data_EncryptDecrypt * command = &context->cmd.Data_EncryptDecrypt;
254 IFAPI_OBJECT *encKeyObject;
255 TPM2B_PUBLIC_KEY_RSA *tpmCipherText = NULL;
256
257 switch (context->state) {
258 statecase(context->state, DATA_ENCRYPT_WAIT_FOR_PROFILE);
259 /* Retrieve the profile for the provided key in order to get the
260 encryption scheme below. */
261 r = ifapi_profiles_get(&context->profiles, command->keyPath,
262 &command->profile);
263 return_try_again(r);
264 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
265
266 /* Initialize a session used for authorization and parameter encryption. */
267 r = ifapi_get_sessions_async(context,
268 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
269 TPMA_SESSION_ENCRYPT | TPMA_SESSION_DECRYPT, 0);
270 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
271
272 fallthrough;
273
274 statecase(context->state, DATA_ENCRYPT_WAIT_FOR_SESSION);
275 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
276 context->profiles.default_profile.nameAlg);
277 return_try_again(r);
278 goto_if_error(r, "Get session.", error_cleanup);
279
280 /* Load the reference key by loading all of its parents starting from the SRK. */
281 r = ifapi_load_keys_async(context, command->keyPath);
282 goto_if_error(r, "Load keys.", error_cleanup);
283
284 fallthrough;
285
286 statecase(context->state, DATA_ENCRYPT_WAIT_FOR_KEY);
287 r = ifapi_load_keys_finish(context, IFAPI_FLUSH_PARENT,
288 &command->key_handle,
289 &command->key_object);
290 return_try_again(r);
291 goto_if_error_reset_state(r, " Load key.", error_cleanup);
292
293 encKeyObject = command->key_object;
294
295 if (encKeyObject->misc.key.public.publicArea.type == TPM2_ALG_RSA) {
296 TPM2B_DATA null_data = { .size = 0, .buffer = {} };
297 TPM2B_PUBLIC_KEY_RSA *rsa_message = (TPM2B_PUBLIC_KEY_RSA *)&context->aux_data;
298 rsa_message->size = context->cmd.Data_EncryptDecrypt.in_dataSize;
299 size_t key_size =
300 encKeyObject->misc.key.public.publicArea.parameters.rsaDetail.keyBits / 8;
301 if (rsa_message->size <= key_size) {
302 memcpy(&rsa_message->buffer[0], context->cmd.Data_EncryptDecrypt.in_data,
303 context->cmd.Data_EncryptDecrypt.in_dataSize);
304
305 /* Received plain text will be encrypted */
306 r = Esys_TRSess_SetAttributes(context->esys, context->session1,
307 TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_DECRYPT,
308 0xff);
309 goto_if_error_reset_state(r, "Set session attributes.", error_cleanup);
310
311 r = Esys_RSA_Encrypt_Async(context->esys,
312 context->cmd.Data_EncryptDecrypt.key_handle,
313 context->session1, ESYS_TR_NONE, ESYS_TR_NONE,
314 rsa_message,
315 &command->profile->rsa_decrypt_scheme,
316 &null_data);
317 goto_if_error(r, "Error esys rsa encrypt", error_cleanup);
318
319 context-> state = DATA_ENCRYPT_WAIT_FOR_RSA_ENCRYPTION;
320 } else {
321 goto_error_reset_state(r, TSS2_FAPI_RC_NOT_IMPLEMENTED,
322 "Size to big for RSA encryption.", error_cleanup);
323 }
324 } else {
325 goto_error(r, TSS2_FAPI_RC_NOT_IMPLEMENTED,
326 "Unsupported algorithm (%" PRIu16 ")",
327 error_cleanup, encKeyObject->misc.key.public.publicArea.type);
328 }
329 fallthrough;
330
331 statecase(context->state, DATA_ENCRYPT_WAIT_FOR_RSA_ENCRYPTION);
332 r = Esys_RSA_Encrypt_Finish(context->esys, &tpmCipherText);
333 return_try_again(r);
334 goto_if_error_reset_state(r, "RSA encryption.", error_cleanup);
335
336 /* Return cipherTextSize if requested by the caller. */
337 if (cipherTextSize)
338 *cipherTextSize = tpmCipherText->size;
339
340 /* Duplicate the outputs for handling off to the caller. */
341 *cipherText = malloc(tpmCipherText->size);
342 goto_if_null2(*cipherText, "Out of memory", r, TSS2_FAPI_RC_MEMORY,
343 error_cleanup);
344
345 memcpy(*cipherText, &tpmCipherText->buffer[0], tpmCipherText->size);
346 SAFE_FREE(tpmCipherText);
347
348 /* Flush the key from the TPM. */
349 r = Esys_FlushContext_Async(context->esys,
350 command->key_handle);
351 goto_if_error(r, "Error: FlushContext", error_cleanup);
352 fallthrough;
353
354 statecase(context->state, DATA_ENCRYPT_WAIT_FOR_FLUSH);
355 r = Esys_FlushContext_Finish(context->esys);
356 return_try_again(r);
357
358 goto_if_error(r, "Error: FlushContext", error_cleanup);
359 command->key_handle = ESYS_TR_NONE;
360 fallthrough;
361
362 statecase(context->state, DATA_ENCRYPT_CLEAN)
363 /* Cleanup the sessions. */
364 r = ifapi_cleanup_session(context);
365 try_again_or_error_goto(r, "Cleanup", error_cleanup);
366
367 break;
368
369 statecasedefault(context->state);
370 }
371
372 context->state = _FAPI_STATE_INIT;
373
374 error_cleanup:
375 /* Cleanup any intermediate results and state stored in the context. */
376 if (command->key_handle != ESYS_TR_NONE)
377 Esys_FlushContext(context->esys, command->key_handle);
378 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
379 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
380 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
381 ifapi_cleanup_ifapi_object(command->key_object);
382 SAFE_FREE(tpmCipherText);
383 SAFE_FREE(command->keyPath);
384 SAFE_FREE(command->in_data);
385 SAFE_FREE(command->out_data);
386 ifapi_session_clean(context);
387 LOG_TRACE("finished");
388 return r;
389 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #include "fapi_crypto.h"
21 #include "fapi_policy.h"
22 #include "ifapi_json_serialize.h"
23 #include "ifapi_json_deserialize.h"
24 #include "tpm_json_deserialize.h"
25 #define LOGMODULE fapi
26 #include "util/log.h"
27 #include "util/aux_util.h"
28
29 /** One-Call function for Fapi_ExportKey
30 *
31 * Given a key it will (if the key is a storage key) duplicate the key and
32 * package up the duplicated key and all keys below it into a file ready to move to
33 * a new TPM.
34 *
35 * @param[in,out] context The FAPI_CONTEXT
36 * @param[in] pathOfKeyToDuplicate The path to the root of the subtree to
37 * export.
38 * @param[in] pathToPublicKeyOfNewParent The path to the public key of the new
39 * parent. May be NULL
40 * @param[out] exportedData The exported subtree
41 *
42 * @retval TSS2_RC_SUCCESS: if the function call was a success.
43 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, pathOfKeyToDuplicate
44 * or exportedData is NULL.
45 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
46 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if pathOfKeyToDuplicate or
47 * pathToPublicKeyOfNewParent does not map to a . FAPI object.
48 * @retval TSS2_FAPI_RC_BAD_KEY: if the key at pathToPublicKeyOfNewParent is not
49 * suitable for the requeste operation.
50 * @retval TSS2_FAPI_RC_KEY_NOT_DUPLICABLE: if the key is not a duplicable key.
51 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
52 * operation already pending.
53 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
54 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
55 * internal operations or return parameters.
56 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
57 * config file.
58 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
59 * during authorization.
60 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
61 * the function.
62 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
63 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
64 * this function needs to be called again.
65 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
66 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
67 * is not set.
68 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
69 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
70 * was not successful.
71 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
72 */
73 TSS2_RC
74 Fapi_ExportKey(
75 FAPI_CONTEXT *context,
76 char const *pathOfKeyToDuplicate,
77 char const *pathToPublicKeyOfNewParent,
78 char **exportedData)
79 {
80 LOG_TRACE("called for context:%p", context);
81
82 TSS2_RC r, r2;
83
84 /* Check for NULL parameters */
85 check_not_null(context);
86 check_not_null(pathOfKeyToDuplicate);
87 check_not_null(exportedData);
88
89 /* Check whether TCTI and ESYS are initialized */
90 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
91 TSS2_FAPI_RC_NO_TPM);
92
93 /* If the async state automata of FAPI shall be tested, then we must not set
94 the timeouts of ESYS to blocking mode.
95 During testing, the mssim tcti will ensure multiple re-invocations.
96 Usually however the synchronous invocations of FAPI shall instruct ESYS
97 to block until a result is available. */
98 #ifndef TEST_FAPI_ASYNC
99 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
100 return_if_error_reset_state(r, "Set Timeout to blocking");
101 #endif /* TEST_FAPI_ASYNC */
102
103 r = Fapi_ExportKey_Async(context, pathOfKeyToDuplicate,
104 pathToPublicKeyOfNewParent);
105 return_if_error_reset_state(r, "ExportKey");
106
107 do {
108 /* We wait for file I/O to be ready if the FAPI state automata
109 are in a file I/O state. */
110 r = ifapi_io_poll(&context->io);
111 return_if_error(r, "Something went wrong with IO polling");
112
113 /* Repeatedly call the finish function, until FAPI has transitioned
114 through all execution stages / states of this invocation. */
115 r = Fapi_ExportKey_Finish(context, exportedData);
116 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
117
118 /* Reset the ESYS timeout to non-blocking, immediate response. */
119 r2 = Esys_SetTimeout(context->esys, 0);
120 return_if_error(r2, "Set Timeout to non-blocking");
121
122 return_if_error_reset_state(r, "ExportKey");
123
124 LOG_TRACE("finished");
125 return TSS2_RC_SUCCESS;
126 }
127
128 /** Asynchronous function for Fapi_ExportKey
129 *
130 * Given a key it will (if the key is a storage key) duplicate the key and
131 * package up the duplicated key and all keys below it into a file ready to move to
132 * a new TPM.
133 *
134 * Call Fapi_ExportKey_Finish to finish the execution of this command.
135 *
136 * @param[in,out] context The FAPI_CONTEXT
137 * @param[in] pathOfKeyToDuplicate The path to the root of the subtree to
138 * export.
139 * @param[in] pathToPublicKeyOfNewParent The path to the public key of the new
140 * parent
141 *
142 * @retval TSS2_RC_SUCCESS: if the function call was a success.
143 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or pathOfKeyToDuplicate
144 * is NULL.
145 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
146 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if pathOfKeyToDuplicate or
147 * pathToPublicKeyOfNewParent does not map to a . FAPI object.
148 * @retval TSS2_FAPI_RC_BAD_KEY: if the key at pathToPublicKeyOfNewParent is not
149 * suitable for the requeste operation.
150 * @retval TSS2_FAPI_RC_KEY_NOT_DUPLICABLE: if the key is not a duplicable key.
151 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
152 * operation already pending.
153 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
154 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
155 * internal operations or return parameters.
156 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
157 * config file.
158 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
159 * during authorization.
160 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
161 * the function.
162 */
163 TSS2_RC
164 Fapi_ExportKey_Async(
165 FAPI_CONTEXT *context,
166 char const *pathOfKeyToDuplicate,
167 char const *pathToPublicKeyOfNewParent)
168 {
169 LOG_TRACE("called for context:%p", context);
170 LOG_TRACE("pathOfKeyToDuplicate: %s", pathOfKeyToDuplicate);
171 LOG_TRACE("pathToPublicKeyOfNewParent: %s", pathToPublicKeyOfNewParent);
172
173 TSS2_RC r;
174
175 /* Check for NULL parameters */
176 check_not_null(context);
177 check_not_null(pathOfKeyToDuplicate);
178
179 /* Helpful alias pointers */
180 IFAPI_ExportKey * command = &context->cmd.ExportKey;
181
182 /* Reset all context-internal session state information. */
183 r = ifapi_session_init(context);
184 return_if_error(r, "Initialize NV_CreateNv");
185
186 /* Copy parameters to context for use during _Finish. */
187 command->pathOfKeyToDuplicate = NULL;
188 command->pathToPublicKeyOfNewParent = NULL;
189 strdup_check(command->pathOfKeyToDuplicate, pathOfKeyToDuplicate,
190 r, error_cleanup);
191 strdup_check(command->pathToPublicKeyOfNewParent,
192 pathToPublicKeyOfNewParent, r, error_cleanup);
193
194 if (!pathToPublicKeyOfNewParent) {
195 /* Only public key of KeyToDuplocate will be exported */
196 r = ifapi_keystore_load_async(&context->keystore, &context->io,
197 pathOfKeyToDuplicate);
198 return_if_error2(r, "Could not open: %s", pathOfKeyToDuplicate);
199
200 /* Initialize the context state for this operation. */
201 context->state = EXPORT_KEY_READ_PUB_KEY;
202 } else {
203 /* The public key of the new parent is needed for duplication */
204 r = ifapi_keystore_load_async(&context->keystore, &context->io,
205 pathToPublicKeyOfNewParent);
206 return_if_error2(r, "Could not open: %s", pathToPublicKeyOfNewParent);
207
208 /* Initialize the context state for this operation. */
209 context->state = EXPORT_KEY_READ_PUB_KEY_PARENT;
210 }
211 LOG_TRACE("finished");
212 return r;
213
214 error_cleanup:
215 /* Cleanup duplicated input parameters that were copied before. */
216 SAFE_FREE(command->pathOfKeyToDuplicate);
217 SAFE_FREE(command->pathToPublicKeyOfNewParent);
218 return r;
219 }
220
221 /** Asynchronous finish function for Fapi_ExportKey
222 *
223 * This function should be called after a previous Fapi_ExportKey_Async.
224 *
225 * @param[in,out] context The FAPI_CONTEXT
226 * @param[out] exportedData The exported subtree
227 *
228 * @retval TSS2_RC_SUCCESS: if the function call was a success.
229 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or exportedData is NULL.
230 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
231 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
232 * operation already pending.
233 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
234 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
235 * internal operations or return parameters.
236 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
237 * complete. Call this function again later.
238 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
239 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
240 * the function.
241 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
242 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
243 * during authorization.
244 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
245 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
246 * is not set.
247 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
248 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
249 * was not successful.
250 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
251 * config file.
252 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
253 */
254 TSS2_RC
255 Fapi_ExportKey_Finish(
256 FAPI_CONTEXT *context,
257 char **exportedData)
258 {
259 LOG_TRACE("called for context:%p", context);
260
261 TSS2_RC r;
262 json_object *jsoOut = NULL;
263 int sizePem;
264 TPM2B_ENCRYPTED_SECRET *encryptedSeed = NULL;
265 TPM2B_PRIVATE *duplicate = NULL;
266 IFAPI_OBJECT commandObject = {0};
267 IFAPI_OBJECT parentKeyObject = {0};
268 ESYS_TR auth_session;
269
270 /* Check for NULL parameters */
271 check_not_null(context);
272 check_not_null(exportedData);
273
274 /* Helpful alias pointers */
275 IFAPI_ExportKey * command = &context->cmd.ExportKey;
276 IFAPI_OBJECT *pubKey = &command->pub_key;
277 IFAPI_OBJECT *exportTree = &command->export_tree;
278 IFAPI_DUPLICATE * keyTree = &exportTree->misc.key_tree;
279 pubKey->misc.ext_pub_key.certificate = NULL;
280
281 switch (context->state) {
282 statecase(context->state, EXPORT_KEY_READ_PUB_KEY);
283 /* This is the entry point if only the public key shall be exported
284 because no new parent key for encrypting the private portion was
285 provided by the caller. */
286 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
287 &commandObject);
288 return_try_again(r);
289 return_if_error_reset_state(r, "read_finish failed");
290
291 if (commandObject.objectType != IFAPI_KEY_OBJ) {
292 /* No key object was loaded */
293 ifapi_cleanup_ifapi_object(&commandObject);
294 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is not a key object.",
295 cleanup, command->pathOfKeyToDuplicate);
296 }
297
298 pubKey->objectType = IFAPI_EXT_PUB_KEY_OBJ;
299 pubKey->misc.ext_pub_key.public = commandObject.misc.key.public;
300
301 /* Convert the TPM key format to PEM. */
302 r = ifapi_pub_pem_key_from_tpm(&pubKey->misc.ext_pub_key.public,
303 &pubKey->misc.ext_pub_key.pem_ext_public,
304 &sizePem);
305 goto_if_error(r, "Convert public TPM key to pem.", cleanup);
306
307 r = ifapi_json_IFAPI_OBJECT_serialize(pubKey, &jsoOut);
308 goto_if_error(r, "Error serialize FAPI KEY object", cleanup);
309
310 *exportedData = strdup(json_object_to_json_string_ext(jsoOut,
311 JSON_C_TO_STRING_PRETTY));
312 goto_if_null2(*exportedData, "Converting json to string", r,
313 TSS2_FAPI_RC_MEMORY, cleanup);
314
315 break;
316
317 statecase(context->state, EXPORT_KEY_READ_PUB_KEY_PARENT);
318 /* This is the entry point if a new parent key was provided and
319 the private portion shall be re-encrypted. */
320 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
321 &parentKeyObject);
322 if (r != TSS2_RC_SUCCESS) {
323 ifapi_cleanup_ifapi_object(&parentKeyObject);
324 }
325 return_try_again(r);
326 return_if_error_reset_state(r, "read_finish failed");
327
328 if (parentKeyObject.objectType != IFAPI_EXT_PUB_KEY_OBJ) {
329 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "No public key in %s",
330 cleanup, command->pathToPublicKeyOfNewParent);
331 }
332
333 /* Store the public information of the new parent in the context
334 and cleanup all other metadata for this key. */
335 command->public_parent = parentKeyObject.misc.ext_pub_key.public;
336 ifapi_cleanup_ifapi_object(&parentKeyObject);
337
338 /* Initialize a session used for authorization and parameter encryption. */
339 r = ifapi_get_sessions_async(context,
340 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
341 TPMA_SESSION_DECRYPT, 0);
342 goto_if_error_reset_state(r, "Create sessions", cleanup);
343
344 fallthrough;
345
346 statecase(context->state, EXPORT_KEY_WAIT_FOR_KEY);
347 /* Load the key to be duplicated. */
348 r = ifapi_load_key(context, command->pathOfKeyToDuplicate,
349 &command->key_object);
350 return_try_again(r);
351 goto_if_error(r, "Fapi load key.", cleanup);
352
353 context->duplicate_key = command->key_object;
354
355 /* Load the new parent key. */
356 r = Esys_LoadExternal_Async(context->esys,
357 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
358 NULL, &command->public_parent,
359 TPM2_RH_OWNER);
360 goto_if_error(r, "LoadExternal_Async", cleanup);
361
362 fallthrough;
363
364 statecase(context->state, EXPORT_KEY_WAIT_FOR_EXT_KEY);
365 r = Esys_LoadExternal_Finish(context->esys,
366 &command->handle_ext_key);
367 try_again_or_error_goto(r, "Load external key.", cleanup);
368
369 fallthrough;
370
371 statecase(context->state, EXPORT_KEY_WAIT_FOR_AUTHORIZATON);
372 /* Authorize against the key to be exported. */
373 r = ifapi_authorize_object(context, command->key_object, &auth_session);
374 return_try_again(r);
375 goto_if_error(r, "Authorize key.", cleanup);
376
377 TPM2B_DATA encryptionKey;
378 TPMT_SYM_DEF_OBJECT symmetric;
379
380 symmetric.algorithm = TPM2_ALG_NULL;
381 encryptionKey.size = 0;
382
383 /* Duplicate the key; i.e. re-encrypt the private key with
384 the public key of the new parent. */
385 r = Esys_Duplicate_Async(context->esys,
386 command->key_object->handle,
387 command->handle_ext_key,
388 auth_session,
389 ESYS_TR_NONE, ESYS_TR_NONE,
390 &encryptionKey, &symmetric);
391 goto_if_error(r, "Duplicate", cleanup);
392
393 fallthrough;
394
395 statecase(context->state, EXPORT_KEY_WAIT_FOR_DUPLICATE);
396 exportTree->objectType = IFAPI_DUPLICATE_OBJ;
397 r = Esys_Duplicate_Finish(context->esys, NULL, &duplicate, &encryptedSeed);
398 try_again_or_error_goto(r, "Duplicate", cleanup);
399
400 /* Store and JSON encode the data to be returned. */
401 /* Note: keyTree = &exportTree->misc.key_tree */
402 keyTree->encrypted_seed = *encryptedSeed;
403 SAFE_FREE(encryptedSeed);
404 keyTree->duplicate = *duplicate;
405 SAFE_FREE(duplicate);
406 keyTree->public =
407 command->key_object->misc.key.public;
408 keyTree->public_parent = command->public_parent;
409
410 /* For the policy added no cleanup is needed. The cleanup will
411 be done with the object cleanup. */
412 keyTree->policy = command->key_object->policy;
413 r = ifapi_get_json(context, exportTree, exportedData);
414 goto_if_error2(r, "get JSON for exported data.", cleanup);
415
416 fallthrough;
417
418 statecase(context->state, EXPORT_KEY_WAIT_FOR_FLUSH1);
419 /* Flush the key to be exported from the TPM. */
420 r = ifapi_flush_object(context, command->key_object->handle);
421 return_try_again(r);
422 goto_if_error(r, "Flush key", cleanup);
423
424 fallthrough;
425
426 statecase(context->state, EXPORT_KEY_WAIT_FOR_FLUSH2);
427 /* Flush the new parent key from the TPM. */
428 r = ifapi_flush_object(context, command->handle_ext_key);
429 return_try_again(r);
430 goto_if_error(r, "Flush key", cleanup);
431
432 fallthrough;
433
434 statecase(context->state, EXPORT_KEY_CLEANUP)
435 /* Cleanup the sessions used for authorization. */
436 r = ifapi_cleanup_session(context);
437 try_again_or_error_goto(r, "Cleanup", cleanup);
438
439 break;
440
441 statecasedefault(context->state);
442 }
443
444 cleanup:
445 /* Cleanup any intermediate results and state stored in the context. */
446 if (command->key_object) {
447 ifapi_cleanup_ifapi_object(command->key_object);
448 }
449 if (jsoOut != NULL) {
450 json_object_put(jsoOut);
451 }
452 context->duplicate_key = NULL;
453 context->state = _FAPI_STATE_INIT;
454 ifapi_cleanup_ifapi_object(&parentKeyObject);
455 ifapi_cleanup_ifapi_object(&commandObject);
456 ifapi_session_clean(context);
457 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
458 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
459 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
460 SAFE_FREE(pubKey->misc.ext_pub_key.pem_ext_public);
461 SAFE_FREE(pubKey->misc.ext_pub_key.certificate);
462 SAFE_FREE(command->pathOfKeyToDuplicate);
463 SAFE_FREE(command->pathToPublicKeyOfNewParent);
464 LOG_TRACE("finished");
465 return r;
466 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include "tss2_fapi.h"
11 #include "fapi_int.h"
12 #include "fapi_util.h"
13 #include "tss2_esys.h"
14 #include "fapi_policy.h"
15 #define LOGMODULE fapi
16 #include "util/log.h"
17 #include "util/aux_util.h"
18
19 /** One-Call function for Fapi_ExportPolicy
20 *
21 * Exports a policy to a JSON encoded byte buffer.
22 *
23 * @param[in,out] context The FAPI_CONTEXT
24 * @param[in] path The path to the policy that is to be exported
25 * @param[out] jsonPolicy The JSON-encoded policy. jsonPolicy MUST NOT be NULL.
26 *
27 * @retval TSS2_RC_SUCCESS: if the function call was a success.
28 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, path or jsonPolicy is NULL.
29 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
30 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI policy.
31 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
32 * operation already pending.
33 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
34 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
35 * internal operations or return parameters.
36 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
37 * config file.
38 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
39 * this function needs to be called again.
40 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
41 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
42 * the function.
43 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
44 * during authorization.
45 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
46 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
47 */
48 TSS2_RC
49 Fapi_ExportPolicy(
50 FAPI_CONTEXT *context,
51 char const *path,
52 char **jsonPolicy)
53 {
54 LOG_TRACE("called for context:%p", context);
55
56 TSS2_RC r, r2;
57
58 /* Check for NULL parameters */
59 check_not_null(context);
60 check_not_null(path);
61 check_not_null(jsonPolicy);
62
63 /* Check whether TCTI and ESYS are initialized */
64 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
65 TSS2_FAPI_RC_NO_TPM);
66
67 /* If the async state automata of FAPI shall be tested, then we must not set
68 the timeouts of ESYS to blocking mode.
69 During testing, the mssim tcti will ensure multiple re-invocations.
70 Usually however the synchronous invocations of FAPI shall instruct ESYS
71 to block until a result is available. */
72 #ifndef TEST_FAPI_ASYNC
73 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
74 return_if_error_reset_state(r, "Set Timeout to blocking");
75 #endif /* TEST_FAPI_ASYNC */
76
77 r = Fapi_ExportPolicy_Async(context, path);
78 return_if_error_reset_state(r, "PolicyExport");
79
80 do {
81 /* We wait for file I/O to be ready if the FAPI state automata
82 are in a file I/O state. */
83 r = ifapi_io_poll(&context->io);
84 return_if_error(r, "Something went wrong with IO polling");
85
86 /* Repeatedly call the finish function, until FAPI has transitioned
87 through all execution stages / states of this invocation. */
88 r = Fapi_ExportPolicy_Finish(context, jsonPolicy);
89 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
90
91 /* Reset the ESYS timeout to non-blocking, immediate response. */
92 r2 = Esys_SetTimeout(context->esys, 0);
93 return_if_error(r2, "Set Timeout to non-blocking");
94
95 return_if_error_reset_state(r, "PolicyExport");
96
97 return TSS2_RC_SUCCESS;
98
99 }
100
101 /** Asynchronous function for Fapi_ExportPolicy
102 *
103 * Exports a policy to a JSON encoded byte buffer.
104 *
105 * Call Fapi_ExportPolicy_Finish to finish the execution of this command.
106 *
107 * @param[in,out] context The FAPI_CONTEXT
108 * @param[in] path The path to the policy that is to be exported
109 *
110 * @retval TSS2_RC_SUCCESS: if the function call was a success.
111 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
112 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
113 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI policy.
114 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
115 * operation already pending.
116 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
117 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
118 * internal operations or return parameters.
119 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
120 * config file.
121 */
122 TSS2_RC
123 Fapi_ExportPolicy_Async(
124 FAPI_CONTEXT *context,
125 char const *path)
126 {
127 LOG_TRACE("called for context:%p", context);
128 LOG_TRACE("path: %s", path);
129
130 TSS2_RC r;
131
132 /* Check for NULL parameters */
133 check_not_null(context);
134 check_not_null(path);
135
136 /* Helpful alias pointers */
137 IFAPI_ExportPolicy * command = &context->cmd.ExportPolicy;
138
139 /* Reset all context-internal session state information. */
140 r = ifapi_session_init(context);
141 return_if_error(r, "Initialize PolicyExport");
142
143 /* Initialize the context state for this operation. */
144 if (ifapi_path_type_p(path, IFAPI_POLICY_PATH)) {
145 context->state = POLICY_EXPORT_READ_POLICY;
146 } else {
147 context->state = POLICY_EXPORT_READ_OBJECT;
148 }
149
150 /* Copy parameters to context for use during _Finish. */
151 strdup_check(command->path, path, r ,error_cleanup);
152 memset(&command->object, 0, sizeof(IFAPI_OBJECT));
153
154 LOG_TRACE("finished");
155 return TSS2_RC_SUCCESS;
156
157 error_cleanup:
158 /* Cleanup duplicated input parameters that were copied before. */
159 SAFE_FREE(command->path);
160 return r;
161 }
162
163 /** Asynchronous finish function for Fapi_ExportPolicy
164 *
165 * This function should be called after a previous Fapi_ExportPolicy_Async.
166 *
167 * @param[in,out] context The FAPI_CONTEXT
168 * @param[out] jsonPolicy The JSON-encoded policy. jsonPolicy MUST NOT be NULL.
169 *
170 * @retval TSS2_RC_SUCCESS: if the function call was a success.
171 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or jsonPolicy is NULL.
172 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
173 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
174 * operation already pending.
175 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
176 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
177 * internal operations or return parameters.
178 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
179 * complete. Call this function again later.
180 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
181 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
182 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
183 * the function.
184 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
185 * during authorization.
186 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
187 */
188 TSS2_RC
189 Fapi_ExportPolicy_Finish(
190 FAPI_CONTEXT *context,
191 char **jsonPolicy)
192 {
193 LOG_TRACE("called for context:%p", context);
194
195 TPMS_POLICY policy = {0};
196 json_object *jso = NULL;
197 TSS2_RC r;
198
199 /* Check for NULL parameters */
200 check_not_null(context);
201 check_not_null(jsonPolicy);
202
203 /* Helpful alias pointers */
204 IFAPI_ExportPolicy * command = &context->cmd.ExportPolicy;
205
206 switch (context->state) {
207 statecase(context->state, POLICY_EXPORT_READ_POLICY);
208 /* This is the entry point if a policy from the policy store shall
209 be exported. */
210 /* Load the policy to be exported from the policy store. */
211 r = ifapi_policy_store_load_async(&context->pstore, &context->io,
212 command->path);
213 goto_if_error2(r, "Can't open: %s", error_cleanup,
214 command->path);
215 fallthrough;
216
217 statecase(context->state, POLICY_EXPORT_READ_POLICY_FINISH);
218 r = ifapi_policy_store_load_finish(&context->pstore, &context->io, &policy);
219 return_try_again(r);
220 return_if_error_reset_state(r, "read_finish failed");
221
222 /* Serialize the policy to JSON. */
223 r = ifapi_json_TPMS_POLICY_serialize(&policy, &jso);
224 goto_if_error(r, "Serialize policy", error_cleanup);
225
226 /* Duplicate the JSON string to be returned to the caller. */
227 strdup_check(*jsonPolicy,
228 json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY),
229 r, error_cleanup);
230
231 break;
232 statecase(context->state, POLICY_EXPORT_READ_OBJECT);
233 /* This is the entry point if a policy for a key from the key store
234 shall be exported. */
235 memset(&command->object, 0, sizeof(IFAPI_OBJECT));
236 /* Load the key meta data from the keystore. */
237 r = ifapi_keystore_load_async(&context->keystore, &context->io,
238 command->path);
239 return_if_error2(r, "Could not open: %s", command->path);
240 fallthrough;
241
242 statecase(context->state, POLICY_EXPORT_READ_OBJECT_FINISH);
243 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
244 &command->object);
245 return_try_again(r);
246 return_if_error_reset_state(r, "read_finish failed");
247
248 goto_if_null2(command->object.policy,
249 "Object has no policy",
250 r, TSS2_FAPI_RC_BAD_PATH, error_cleanup);
251
252 /* Serialize the policy to JSON. */
253 r = ifapi_json_TPMS_POLICY_serialize(context->
254 cmd.ExportPolicy.object.policy, &jso);
255 goto_if_error(r, "Serialize policy", error_cleanup);
256
257 /* Duplicate the JSON string to be returned to the caller. */
258 strdup_check(*jsonPolicy,
259 json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY),
260 r, error_cleanup);
261 break;
262
263 statecasedefault(context->state);
264 }
265
266 /* Cleanup any intermediate results and state stored in the context. */
267 context->state = _FAPI_STATE_INIT;
268 if (jso)
269 json_object_put(jso);
270 ifapi_cleanup_ifapi_object(&command->object);
271 ifapi_cleanup_policy(&policy);
272 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
273 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
274 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
275 SAFE_FREE(command->path);
276 LOG_TRACE("finished");
277 return TSS2_RC_SUCCESS;
278
279 error_cleanup:
280 /* Cleanup any intermediate results and state stored in the context. */
281 if (command->object.objectType)
282 ifapi_cleanup_ifapi_object(&command->object);
283 if (jso)
284 json_object_put(jso);
285 ifapi_cleanup_policy(&policy);
286 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
287 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
288 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
289 SAFE_FREE(command->path);
290 context->state = _FAPI_STATE_INIT;
291 return r;
292 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #ifndef NO_DL
11 #include <dlfcn.h>
12 #endif /* NO_DL */
13 #include <stdlib.h>
14
15 #include<unistd.h>
16
17 #include "tss2_fapi.h"
18 #include "tss2_tctildr.h"
19 #include "fapi_int.h"
20 #include "fapi_util.h"
21 #include "tss2_esys.h"
22 #define LOGMODULE fapi
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 /** One-Call function for Fapi_Finalize
27 *
28 * Fapi_Finalize() finalizes a context by closing IPC/RPC connections and freeing
29 * its consumed memory.
30 *
31 * @param[in] context The FAPI_CONTEXT
32 */
33 void
34 Fapi_Finalize(
35 FAPI_CONTEXT **context)
36 {
37 LOG_TRACE("called for context:%p", context);
38
39 /* Check for NULL parameters */
40 if (!context || !*context) {
41 LOG_WARNING("Attempting to free NULL context");
42 return;
43 }
44
45 LOG_DEBUG("called: context: %p, *context: %p", context,
46 (context != NULL) ? *context : NULL);
47
48 /* Finalize the profiles module. */
49 ifapi_profiles_finalize(&(*context)->profiles);
50
51 /* Finalize the TCTI and ESYS contexts. */
52 TSS2_TCTI_CONTEXT *tcti = NULL;
53
54 if ((*context)->esys) {
55 Esys_GetTcti((*context)->esys, &tcti);
56 Esys_Finalize(&((*context)->esys));
57 if (tcti) {
58 LOG_TRACE("Finalizing TCTI");
59 Tss2_TctiLdr_Finalize(&tcti);
60 }
61 }
62
63 /* Finalize the keystore module. */
64 ifapi_cleanup_ifapi_keystore(&(*context)->keystore);
65
66 /* Finalize the policy module. */
67 SAFE_FREE((*context)->pstore.policydir);
68
69 /* Finalize leftovers from provisioning. */
70 SAFE_FREE((*context)->cmd.Provision.root_crt);
71 SAFE_FREE((*context)->cmd.Provision.intermed_crt);
72 SAFE_FREE((*context)->cmd.Provision.pem_cert);
73
74 /* Finalize the config module. */
75 SAFE_FREE((*context)->config.profile_dir);
76 SAFE_FREE((*context)->config.user_dir);
77 SAFE_FREE((*context)->config.keystore_dir);
78 SAFE_FREE((*context)->config.profile_name);
79 SAFE_FREE((*context)->config.tcti);
80 SAFE_FREE((*context)->config.log_dir);
81 SAFE_FREE((*context)->config.ek_cert_file);
82 SAFE_FREE((*context)->config.intel_cert_service);
83
84 /* Finalize the eventlog module. */
85 SAFE_FREE((*context)->eventlog.log_dir);
86
87 /* Finalize all remaining object of the context. */
88 ifapi_free_objects(*context);
89
90 /* Free the context's memory. */
91 free(*context);
92 *context = NULL;
93
94 LOG_DEBUG("finished");
95 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11
12 /** Frees a FAPI allocated return buffer.
13 *
14 * Fapi_Free is a helper function that is a wrapper around free().
15 * This allows programs that are built using a different version
16 * of the C runtime to free memory that has been allocated by the
17 * esys library on Windows.
18 *
19 * @param[in] ptr A pointer to the object that is to be freed.
20 */
21 void
22 Fapi_Free(void *ptr)
23 {
24 if (ptr != NULL) {
25 free(ptr);
26 }
27 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 /** One-Call function for Fapi_GetAppData
25 *
26 * Every object has a description field that can be retrieved in order to obtain
27 * additional information in its “path” entry.
28 *
29 * @param[in,out] context The FAPI_CONTEXT
30 * @param[in] path The path to the object for which the appData is returned
31 * @param[out] appData A copy of the appData. May be NULL (callee-allocated)
32 * @param[out] appDataSize The size of the returned AppData. May be NULL
33 *
34 * @retval TSS2_RC_SUCCESS: if the function call was a success.
35 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
36 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
37 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
38 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
39 * operation already pending.
40 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
41 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
42 * internal operations or return parameters.
43 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
44 * config file.
45 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
46 * during authorization.
47 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
48 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
49 * the function.
50 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
51 * this function needs to be called again.
52 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
53 */
54 TSS2_RC
55 Fapi_GetAppData(
56 FAPI_CONTEXT *context,
57 char const *path,
58 uint8_t **appData,
59 size_t *appDataSize)
60 {
61 LOG_TRACE("called for context:%p", context);
62
63 TSS2_RC r;
64
65 /* Check for NULL parameters */
66 check_not_null(context);
67 check_not_null(path);
68
69 r = Fapi_GetAppData_Async(context, path);
70 return_if_error_reset_state(r, "Path_SetDescription");
71
72 do {
73 /* We wait for file I/O to be ready if the FAPI state automata
74 are in a file I/O state. */
75 r = ifapi_io_poll(&context->io);
76 return_if_error(r, "Something went wrong with IO polling");
77
78 /* Repeatedly call the finish function, until FAPI has transitioned
79 through all execution stages / states of this invocation. */
80 r = Fapi_GetAppData_Finish(context, appData, appDataSize);
81 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
82
83 return_if_error_reset_state(r, "Path_SetDescription");
84
85 LOG_TRACE("finished");
86 return TSS2_RC_SUCCESS;
87 }
88
89 /** Asynchronous function for Fapi_GetAppData
90 *
91 * Every object has a description field that can be retrieved in order to obtain
92 * additional information in its “path” entry.
93 *
94 * Call Fapi_GetAppData_Finish to finish the execution of this command.
95 *
96 * @param[in,out] context The FAPI_CONTEXT
97 * @param[in] path The path to the object for which the appData is returned
98 *
99 * @retval TSS2_RC_SUCCESS: if the function call was a success.
100 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
101 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
102 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
103 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
104 * operation already pending.
105 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
106 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
107 * internal operations or return parameters.
108 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
109 * config file.
110 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
111 * during authorization.
112 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
113 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
114 * the function.
115 */
116 TSS2_RC
117 Fapi_GetAppData_Async(
118 FAPI_CONTEXT *context,
119 char const *path)
120 {
121 LOG_TRACE("called for context:%p", context);
122 LOG_TRACE("path: %s", path);
123
124 TSS2_RC r;
125
126 /* Check for NULL parameters */
127 check_not_null(context);
128 check_not_null(path);
129
130 /* Reset all context-internal session state information. */
131 r = ifapi_session_init(context);
132 return_if_error(r, "Initialize GetAppData");
133
134 /* Load the object metadata from keystore. */
135 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
136 return_if_error2(r, "Could not open: %s", path);
137
138 context->state = PATH_GET_DESCRIPTION_READ;
139 LOG_TRACE("finished");
140 return TSS2_RC_SUCCESS;
141 }
142
143 /** Asynchronous finish function for Fapi_GetAppData
144 *
145 * This function should be called after a previous Fapi_GetAppData_Async.
146 *
147 * @param[in,out] context The FAPI_CONTEXT
148 * @param[out] appData A copy of the appData. May be Null (callee-allocated)
149 * @param[out] appDataSize The size of the returned AppData. May be NULL
150 *
151 * @retval TSS2_RC_SUCCESS: if the function call was a success.
152 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
153 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
154 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
155 * operation already pending.
156 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
157 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
158 * internal operations or return parameters.
159 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
160 * complete. Call this function again later.
161 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
162 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
163 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
164 * the function.
165 */
166 TSS2_RC
167 Fapi_GetAppData_Finish(
168 FAPI_CONTEXT *context,
169 uint8_t **appData,
170 size_t *appDataSize)
171 {
172 LOG_TRACE("called for context:%p", context);
173
174 TSS2_RC r;
175 IFAPI_OBJECT object;
176 UINT8_ARY *objAppData;
177
178 /* Check for NULL parameters */
179 check_not_null(context);
180
181 switch (context->state) {
182 statecase(context->state, PATH_GET_DESCRIPTION_READ);
183 r = ifapi_keystore_load_finish(&context->keystore, &context->io, &object);
184 return_try_again(r);
185 return_if_error_reset_state(r, "read_finish failed");
186
187 /* Get the application data from the metadata objects. */
188 switch (object.objectType) {
189 case IFAPI_KEY_OBJ:
190 objAppData = &object.misc.key.appData;
191 break;
192 case IFAPI_NV_OBJ:
193 objAppData = &object.misc.nv.appData;
194 break;
195 default:
196 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "Object has no app data.", cleanup);
197 }
198
199 if (appData) {
200 /* Duplicate the application data to be returned to the caller. */
201 if (objAppData->size) {
202 *appData = malloc(objAppData->size);
203 goto_if_null2(*appData, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
204 cleanup);
205 memcpy(*appData, &objAppData->buffer[0],
206 objAppData->size);
207 } else {
208 *appData = NULL;
209 }
210 }
211 if (appDataSize)
212 *appDataSize = objAppData->size;
213
214 context->state = _FAPI_STATE_INIT;
215 r = TSS2_RC_SUCCESS;
216 break;
217
218 statecasedefault(context->state);
219 }
220
221 cleanup:
222 /* Cleanup any intermediate results and state stored in the context. */
223 ifapi_cleanup_ifapi_object(&object);
224 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
225 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
226 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
227 LOG_TRACE("finished");
228 return r;
229 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16
17 #include "tss2_fapi.h"
18 #include "fapi_int.h"
19 #include "fapi_util.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24 #include "fapi_crypto.h"
25
26 /** One-Call function for Fapi_GetCertificate
27 *
28 * Gets an x.509 certificate for the key at a given path.
29 *
30 * @param[in,out] context The FAPI_CONTEXT
31 * @param[in] path The path to the key whose certificate is created
32 * @param[out] x509certData The PEM-encoded certificate
33 *
34 * @retval TSS2_RC_SUCCESS: if the function call was a success.
35 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, path or x509CertData is
36 * NULL.
37 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
38 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND: if path does not map to a FAPI entity.
39 * @retval TSS2_FAPI_RC_BAD_KEY: if the key is unsuitable for the requested
40 * operation.
41 * @retval TSS2_FAPI_RC_NO_CERTIFICATE: if there is not a x.509 cert associated
42 * with the path of the key.
43 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
44 * operation already pending.
45 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
46 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
47 * internal operations or return parameters.
48 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
49 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
50 * the function.
51 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
52 * this function needs to be called again.
53 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
54 */
55 TSS2_RC
56 Fapi_GetCertificate(
57 FAPI_CONTEXT *context,
58 char const *path,
59 char **x509certData)
60 {
61 LOG_TRACE("called for context:%p", context);
62
63 TSS2_RC r;
64
65 /* Check for NULL parameters */
66 check_not_null(context);
67 check_not_null(path);
68 check_not_null(x509certData);
69
70 r = Fapi_GetCertificate_Async(context, path);
71 return_if_error_reset_state(r, "Key_GetCertificate");
72
73 do {
74 /* We wait for file I/O to be ready if the FAPI state automata
75 are in a file I/O state. */
76 r = ifapi_io_poll(&context->io);
77 return_if_error(r, "Something went wrong with IO polling");
78
79 /* Repeatedly call the finish function, until FAPI has transitioned
80 through all execution stages / states of this invocation. */
81 r = Fapi_GetCertificate_Finish(context, x509certData);
82 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
83
84 return_if_error_reset_state(r, "Key_GetCertificate");
85
86 LOG_TRACE("finished");
87 return TSS2_RC_SUCCESS;
88 }
89
90 /** Asynchronous function for Fapi_GetCertificate
91 *
92 * Gets an x.509 certificate for the key at a given path.
93 *
94 * Call Fapi_GetCertificate_Finish to finish the execution of this command.
95 *
96 * @param[in,out] context The FAPI_CONTEXT
97 * @param[in] path The path to the key whose certificate is created
98 *
99 * @retval TSS2_RC_SUCCESS: if the function call was a success.
100 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
101 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
102 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND: if path does not map to a FAPI entity.
103 * @retval TSS2_FAPI_RC_BAD_KEY: if the key is unsuitable for the requested
104 * operation.
105 * @retval TSS2_FAPI_RC_NO_CERTIFICATE: if there is not a x.509 cert associated
106 * with the path of the key.
107 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
108 * operation already pending.
109 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
110 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
111 * internal operations or return parameters.
112 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
113 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
114 * the function.
115 */
116 TSS2_RC
117 Fapi_GetCertificate_Async(
118 FAPI_CONTEXT *context,
119 char const *path)
120
121 {
122 LOG_TRACE("called for context:%p", context);
123 LOG_TRACE("path: %s", path);
124
125 TSS2_RC r;
126
127 /* Check for NULL parameters */
128 check_not_null(context);
129 check_not_null(path);
130
131 r = ifapi_non_tpm_mode_init(context);
132 return_if_error(r, "Initialize GetCertificate");
133
134 /* Load the object metadata from keystore. */
135 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
136 return_if_error2(r, "Could not open: %s", path);
137
138 /* Initialize the context state for this operation. */
139 context->state = KEY_GET_CERTIFICATE_READ;
140
141 LOG_TRACE("finished");
142 return TSS2_RC_SUCCESS;
143 }
144
145 /** Asynchronous finish function for Fapi_GetCertificate
146 *
147 * This function should be called after a previous Fapi_GetCertificate_Async.
148 *
149 * @param[in,out] context The FAPI_CONTEXT
150 * @param[out] x509certData The PEM-encoded certificate
151 *
152 * @retval TSS2_RC_SUCCESS: if the function call was a success.
153 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or x509certData is NULL.
154 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
155 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
156 * operation already pending.
157 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
158 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
159 * internal operations or return parameters.
160 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
161 * complete. Call this function again later.
162 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
163 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
164 * the function.
165 */
166 TSS2_RC
167 Fapi_GetCertificate_Finish(
168 FAPI_CONTEXT *context,
169 char **x509certData)
170 {
171 LOG_TRACE("called for context:%p", context);
172
173 TSS2_RC r;
174
175 /* Check for NULL parameters */
176 check_not_null(context);
177 check_not_null(x509certData);
178
179 /* Helpful alias pointers */
180 IFAPI_Key_SetCertificate *command = &context->cmd.Key_SetCertificate;
181 IFAPI_OBJECT *keyObject = &command->key_object;
182
183 switch (context->state) {
184 statecase(context->state, KEY_GET_CERTIFICATE_READ)
185 r = ifapi_keystore_load_finish(&context->keystore, &context->io, keyObject);
186 return_try_again(r);
187 return_if_error_reset_state(r, "read_finish failed");
188
189 /* Retrieve the appropriate field from the objects and duplicate its
190 content to be returned to the user. */
191 if (keyObject->objectType == IFAPI_EXT_PUB_KEY_OBJ) {
192 strdup_check(*x509certData, keyObject->misc.ext_pub_key.certificate,
193 r, error_cleanup);
194 } else if (x509certData) {
195 strdup_check(*x509certData, keyObject->misc.key.certificate,
196 r, error_cleanup);
197 }
198
199 context->state = _FAPI_STATE_INIT;
200 r = TSS2_RC_SUCCESS;
201 break;
202
203 statecasedefault(context->state);
204 }
205
206 error_cleanup:
207 /* Cleanup any intermediate results and state stored in the context. */
208 if (keyObject->objectType) {
209 ifapi_cleanup_ifapi_object(keyObject);
210 }
211 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
212 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
213 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
214
215 LOG_TRACE("finished");
216 return r;
217 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 /** One-Call function for Fapi_GetDescription
25 *
26 * Returns the description of a previously stored object.
27 *
28 * @param[in,out] context The FAPI_CONTEXT
29 * @param[in] path The path of the object for which the description is loaded
30 * @param[out] description The description of the object
31 *
32 * @retval TSS2_RC_SUCCESS: if the function call was a success.
33 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, path or description is NULL.
34 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
35 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
36 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
37 * operation already pending.
38 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
39 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
40 * internal operations or return parameters.
41 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
42 * during authorization.
43 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
44 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
45 * the function.
46 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
47 * this function needs to be called again.
48 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
49 */
50 TSS2_RC
51 Fapi_GetDescription(
52 FAPI_CONTEXT *context,
53 char const *path,
54 char **description)
55 {
56 LOG_TRACE("called for context:%p", context);
57
58 TSS2_RC r;
59
60 /* Check for NULL parameters */
61 check_not_null(context);
62 check_not_null(path);
63 check_not_null(description);
64
65 r = Fapi_GetDescription_Async(context, path);
66 return_if_error_reset_state(r, "Path_SetDescription");
67
68 do {
69 /* We wait for file I/O to be ready if the FAPI state automata
70 are in a file I/O state. */
71 r = ifapi_io_poll(&context->io);
72 return_if_error(r, "Something went wrong with IO polling");
73
74 /* Repeatedly call the finish function, until FAPI has transitioned
75 through all execution stages / states of this invocation. */
76 r = Fapi_GetDescription_Finish(context, description);
77 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
78
79 return_if_error_reset_state(r, "Path_SetDescription");
80
81 LOG_TRACE("finished");
82 return TSS2_RC_SUCCESS;
83 }
84
85 /** Asynchronous function for Fapi_GetDescription
86 *
87 * Returns the description of a previously stored object.
88 *
89 * Call Fapi_GetDescription_Finish to finish the execution of this command.
90 *
91 * @param[in,out] context The FAPI_CONTEXT
92 * @param[in] path The path of the object for which the description is loaded
93 *
94 * @retval TSS2_RC_SUCCESS: if the function call was a success.
95 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
96 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
97 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
98 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
99 * operation already pending.
100 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
101 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
102 * internal operations or return parameters.
103 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
104 * during authorization.
105 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
106 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
107 * the function.
108 */
109 TSS2_RC
110 Fapi_GetDescription_Async(
111 FAPI_CONTEXT *context,
112 char const *path)
113 {
114 LOG_TRACE("called for context:%p", context);
115 LOG_TRACE("path: %s", path);
116
117 TSS2_RC r;
118
119 /* Check for NULL parameters */
120 check_not_null(context);
121 check_not_null(path);
122
123 /* Load the object metadata from keystore. */
124 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
125 return_if_error2(r, "Could not open: %s", path);
126
127 /* Initialize the context state for this operation. */
128 context->state = PATH_GET_DESCRIPTION_READ;
129
130 LOG_TRACE("finished");
131 return TSS2_RC_SUCCESS;
132 }
133
134 /** Asynchronous finish function for Fapi_GetDescription
135 *
136 * This function should be called after a previous Fapi_GetDescription_Async.
137 *
138 * @param[in,out] context The FAPI_CONTEXT
139 * @param[out] description The description of the object
140 *
141 * @retval TSS2_RC_SUCCESS: if the function call was a success.
142 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or description is NULL.
143 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
144 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
145 * operation already pending.
146 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
147 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
148 * internal operations or return parameters.
149 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
150 * complete. Call this function again later.
151 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
152 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
153 * the function.
154 */
155 TSS2_RC
156 Fapi_GetDescription_Finish(
157 FAPI_CONTEXT *context,
158 char **description)
159 {
160 LOG_TRACE("called for context:%p", context);
161
162 TSS2_RC r;
163 IFAPI_OBJECT object;
164
165 /* Check for NULL parameters */
166 check_not_null(context);
167 check_not_null(description);
168
169 switch (context->state) {
170 statecase(context->state, PATH_GET_DESCRIPTION_READ);
171 r = ifapi_keystore_load_finish(&context->keystore, &context->io, &object);
172 return_try_again(r);
173 return_if_error_reset_state(r, "read_finish failed");
174
175 /* Retrieve the description from the metadata object. */
176 r = ifapi_get_description(&object, description);
177 ifapi_cleanup_ifapi_object(&object);
178 return_if_error_reset_state(r, "Get description");
179
180 context->state = _FAPI_STATE_INIT;
181 r = TSS2_RC_SUCCESS;
182 break;
183
184 statecasedefault(context->state);
185 }
186 LOG_TRACE("finished");
187 /* Cleanup any intermediate results and state stored in the context. */
188 ifapi_cleanup_ifapi_object(&object);
189 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
190 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
191 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
192 return r;
193 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <json-c/json_util.h>
11 #include <json-c/json_tokener.h>
12 #include <string.h>
13
14 #include "ifapi_json_serialize.h"
15 #include "tss2_fapi.h"
16 #include "fapi_int.h"
17 #include "fapi_util.h"
18 #include "tss2_esys.h"
19 #define LOGMODULE fapi
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 typedef struct {
24 char *description;
25 TPMI_POLICYTYPE capability;
26 UINT32 property;
27 UINT32 max;
28 } IFAPI_INFO_CAP;
29
30 static IFAPI_INFO_CAP info_cap_tab[] = {
31 { "algorithms", TPM2_CAP_ALGS, TPM2_ALG_FIRST, TPM2_MAX_CAP_ALGS},
32 { "handles-transient", TPM2_CAP_HANDLES, TPM2_TRANSIENT_FIRST, TPM2_MAX_CAP_HANDLES},
33 { "handles-persistent", TPM2_CAP_HANDLES, TPM2_PERSISTENT_FIRST, TPM2_MAX_CAP_HANDLES},
34 { "handles-permanent", TPM2_CAP_HANDLES, TPM2_PERMANENT_FIRST, TPM2_MAX_CAP_HANDLES},
35 { "handles-pcr", TPM2_CAP_HANDLES, TPM2_PCR_FIRST, TPM2_MAX_CAP_HANDLES},
36 { "handles-nv-index", TPM2_CAP_HANDLES, TPM2_NV_INDEX_FIRST, TPM2_MAX_CAP_HANDLES},
37 { "handles-loaded-session", TPM2_CAP_HANDLES, TPM2_LOADED_SESSION_FIRST, TPM2_MAX_CAP_HANDLES},
38 { "handles-action-session", TPM2_CAP_HANDLES, TPM2_ACTIVE_SESSION_FIRST, TPM2_MAX_CAP_HANDLES},
39 { "handles-saved-session", TPM2_CAP_HANDLES, TPM2_ACTIVE_SESSION_FIRST, TPM2_MAX_CAP_HANDLES},
40 { "properties-fixed", TPM2_CAP_TPM_PROPERTIES, TPM2_PT_FIXED, TPM2_MAX_TPM_PROPERTIES },
41 { "properties-variable", TPM2_CAP_TPM_PROPERTIES, TPM2_PT_VAR, TPM2_MAX_TPM_PROPERTIES },
42 { "commands", TPM2_CAP_COMMANDS, TPM2_CC_FIRST, TPM2_MAX_CAP_CC },
43 { "pp-commands", TPM2_CAP_PP_COMMANDS, TPM2_CC_FIRST, TPM2_MAX_CAP_CC },
44 { "audit-commands", TPM2_CAP_AUDIT_COMMANDS, TPM2_CC_FIRST, TPM2_MAX_CAP_CC },
45 { "pcrs", TPM2_CAP_PCRS, 0, TPM2_NUM_PCR_BANKS },
46 { "pcr-properties", TPM2_CAP_PCR_PROPERTIES, TPM2_PCR_FIRST, TPM2_MAX_PCR_PROPERTIES },
47 { "ecc-curves", TPM2_CAP_ECC_CURVES, 0, TPM2_MAX_ECC_CURVES },
48 };
49
50 /** One-Call function for Fapi_GetInfo
51 *
52 * Returns a UTF-8 encoded string that identifies the versions of FAPI, TPM,
53 * configurations and other relevant information.
54 *
55 * @param[in,out] context The FAPI_CONTEXT
56 * @param[out] info The byte buffer for the information string
57 *
58 * @retval TSS2_RC_SUCCESS: if the function call was a success.
59 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or info is NULL.
60 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
61 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
62 * operation already pending.
63 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
64 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
65 * internal operations or return parameters.
66 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
67 * config file.
68 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
69 * this function needs to be called again.
70 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
71 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
72 * the function.
73 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
74 */
75 TSS2_RC
76 Fapi_GetInfo(
77 FAPI_CONTEXT *context,
78 char **info)
79 {
80 LOG_TRACE("called for context:%p", context);
81
82 TSS2_RC r, r2;
83
84 /* Check for NULL parameters */
85 check_not_null(context);
86 check_not_null(info);
87
88 /* Check whether TCTI and ESYS are initialized */
89 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
90 TSS2_FAPI_RC_NO_TPM);
91
92 /* If the async state automata of FAPI shall be tested, then we must not set
93 the timeouts of ESYS to blocking mode.
94 During testing, the mssim tcti will ensure multiple re-invocations.
95 Usually however the synchronous invocations of FAPI shall instruct ESYS
96 to block until a result is available. */
97 #ifndef TEST_FAPI_ASYNC
98 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
99 return_if_error_reset_state(r, "Set Timeout to blocking");
100 #endif /* TEST_FAPI_ASYNC */
101
102 r = Fapi_GetInfo_Async(context);
103 return_if_error_reset_state(r, "GetTPMInfo");
104
105 do {
106 /* We wait for file I/O to be ready if the FAPI state automata
107 are in a file I/O state. */
108 r = ifapi_io_poll(&context->io);
109 return_if_error(r, "Something went wrong with IO polling");
110
111 /* Repeatedly call the finish function, until FAPI has transitioned
112 through all execution stages / states of this invocation. */
113 r = Fapi_GetInfo_Finish(context, info);
114 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
115
116 /* Reset the ESYS timeout to non-blocking, immediate response. */
117 r2 = Esys_SetTimeout(context->esys, 0);
118 return_if_error(r2, "Set Timeout to non-blocking");
119
120 return_if_error_reset_state(r, "GetTPMInfo");
121
122 LOG_TRACE("finished");
123 return TSS2_RC_SUCCESS;
124 }
125
126 /** Asynchronous function for Fapi_GetInfo
127 *
128 * Returns a UTF-8 encoded string that identifies the versions of FAPI, TPM,
129 * configurations and other relevant information.
130 *
131 * Call Fapi_GetInfo_Finish to finish the execution of this command.
132 *
133 * @param[in,out] context The FAPI_CONTEXT
134 *
135 * @retval TSS2_RC_SUCCESS: if the function call was a success.
136 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
137 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
138 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
139 * operation already pending.
140 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
141 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
142 * internal operations or return parameters.
143 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
144 * config file.
145 */
146 TSS2_RC
147 Fapi_GetInfo_Async(
148 FAPI_CONTEXT *context)
149 {
150 LOG_TRACE("called for context:%p", context);
151
152 TSS2_RC r;
153
154 /* Check for NULL parameters */
155 check_not_null(context);
156
157 /* Helpful alias pointers */
158 IFAPI_GetInfo * command = &context->cmd.GetInfo;
159
160 /* Reset all context-internal session state information. */
161 r = ifapi_session_init(context);
162 return_if_error(r, "Initialize GetInfo");
163
164 memset(command, 0, sizeof(IFAPI_GetInfo));
165 r = ifapi_capability_init(context);
166 return_if_error(r, "Capability init");
167
168 /* Initialize the context state for this operation. */
169 command->idx_info_cap = 0;
170 context->state = GET_INFO_GET_CAP;
171
172 LOG_TRACE("finished");
173 return TSS2_RC_SUCCESS;
174 }
175
176 /** Asynchronous finish function for Fapi_GetInfo
177 *
178 * This function should be called after a previous Fapi_GetInfo_Async.
179 *
180 * @param[in,out] context The FAPI_CONTEXT
181 * @param[out] info The byte buffer for the information string
182 *
183 * @retval TSS2_RC_SUCCESS: if the function call was a success.
184 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or info is NULL.
185 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
186 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
187 * operation already pending.
188 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
189 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
190 * internal operations or return parameters.
191 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
192 * complete. Call this function again later.
193 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
194 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
195 * the function.
196 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
197 */
198 TSS2_RC
199 Fapi_GetInfo_Finish(
200 FAPI_CONTEXT *context,
201 char **info)
202 {
203 LOG_TRACE("called for context:%p", context);
204
205 TSS2_RC r;
206 json_object *jso = NULL;
207 size_t capIdx;
208
209 /* Check for NULL parameters */
210 check_not_null(context);
211 check_not_null(info);
212
213 /* Helpful alias pointers */
214 IFAPI_GetInfo * command = &context->cmd.GetInfo;
215 IFAPI_INFO *infoObj = &command->info_obj;
216 TPMS_CAPABILITY_DATA *capabilityData = NULL;
217
218 switch (context->state) {
219 case GET_INFO_GET_CAP:
220 /* Initialize the property for the first ESAPI call */
221 command->property
222 = info_cap_tab[command->idx_info_cap].property;
223 fallthrough;
224
225 case GET_INFO_GET_CAP_MORE:
226 /* This state is a helper used from fapi_util.c */
227 fallthrough;
228
229 case GET_INFO_WAIT_FOR_CAP:
230 /* State will be set by sub routine */
231 capIdx = command->idx_info_cap;
232 r = ifapi_capability_get(context,
233 info_cap_tab[capIdx].capability,
234 info_cap_tab[capIdx].max,
235 &capabilityData);
236 return_try_again(r);
237 goto_if_error(r, "Get capability", cleanup);
238
239 infoObj->cap[capIdx].description = info_cap_tab[capIdx].description;
240 infoObj->cap[capIdx].capability = capabilityData;
241 command->property_count = 0;
242 command->idx_info_cap += 1;
243 if (command->idx_info_cap < sizeof(info_cap_tab)
244 / sizeof(info_cap_tab[0])) {
245 /* Not all capabilities have been collected */
246 context->state = GET_INFO_GET_CAP;
247 return TSS2_FAPI_RC_TRY_AGAIN;
248 }
249
250 infoObj->fapi_version = "OSSTSS 2.2.x";
251 infoObj->fapi_config = "Properties of config have to specified by TCG";
252
253 /* Serialize the information. */
254 r = ifapi_json_IFAPI_INFO_serialize(infoObj, &jso);
255 goto_if_error(r, "Error serialize info object", cleanup);
256
257 /* Duplicate the information to be returned to the caller. */
258 *info = strdup(json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY));
259 goto_if_null2(*info, "Out of memory.", r, TSS2_FAPI_RC_MEMORY, cleanup);
260
261 context->state = _FAPI_STATE_INIT;
262 r = TSS2_RC_SUCCESS;
263 break;
264
265 statecasedefault(context->state);
266 }
267
268 cleanup:
269 /* Cleanup any intermediate results and state stored in the context. */
270 json_object_put(jso);
271 for (capIdx = 0; capIdx < IFAPI_MAX_CAP_INFO; capIdx++) {
272 SAFE_FREE(infoObj->cap[capIdx].capability);
273 }
274 LOG_TRACE("finished");
275 return r;
276 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 /** One-Call function for Fapi_GetPlatformCertificates
25 *
26 * Platform certificates for TPM 2.0 can consist not only of a single certificate
27 * but a series of so-called delta certificates.
28 * This function returns the set of Platform certificates concatenated in
29 * a continuous buffer.
30 *
31 * @param[in,out] context The FAPI_CONTEXT
32 * @param[out] certificates The platform certificates
33 * @param[out] certificatesSize The size of the buffer with the certificates.
34 * May be NULL
35 *
36 * @retval TSS2_RC_SUCCESS: if the function call was a success.
37 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or certificates is NULL.
38 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
39 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
40 * operation already pending.
41 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
42 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for internal
43 * operations or return parameters.
44 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
45 * config file.
46 * @retval TSS2_FAPI_RC_NO_CERT if an error did occur during certificate downloading.
47 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
48 * this function needs to be called again.
49 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
50 * is not set.
51 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
52 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
53 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
54 * was not successful.
55 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
56 */
57 TSS2_RC
58 Fapi_GetPlatformCertificates(
59 FAPI_CONTEXT *context,
60 uint8_t **certificates,
61 size_t *certificatesSize)
62 {
63 LOG_TRACE("called for context:%p", context);
64
65 TSS2_RC r, r2;
66
67 /* Check for NULL parameters */
68 check_not_null(context);
69 check_not_null(certificates);
70
71 /* Check whether TCTI and ESYS are initialized */
72 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
73 TSS2_FAPI_RC_NO_TPM);
74
75 /* If the async state automata of FAPI shall be tested, then we must not set
76 the timeouts of ESYS to blocking mode.
77 During testing, the mssim tcti will ensure multiple re-invocations.
78 Usually however the synchronous invocations of FAPI shall instruct ESYS
79 to block until a result is available. */
80 #ifndef TEST_FAPI_ASYNC
81 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
82 return_if_error_reset_state(r, "Set Timeout to blocking");
83 #endif /* TEST_FAPI_ASYNC */
84
85 r = Fapi_GetPlatformCertificates_Async(context);
86 return_if_error_reset_state(r, "Path_PlatformGetCertificate");
87
88 do {
89 /* We wait for file I/O to be ready if the FAPI state automata
90 are in a file I/O state. */
91 r = ifapi_io_poll(&context->io);
92 return_if_error(r, "Something went wrong with IO polling");
93
94 /* Repeatedly call the finish function, until FAPI has transitioned
95 through all execution stages / states of this invocation. */
96 r = Fapi_GetPlatformCertificates_Finish(context, certificates,
97 certificatesSize);
98 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
99
100 /* Reset the ESYS timeout to non-blocking, immediate response. */
101 r2 = Esys_SetTimeout(context->esys, 0);
102 return_if_error(r2, "Set Timeout to non-blocking");
103
104 return_if_error_reset_state(r, "Path_PlatformGetCertificate");
105
106 LOG_TRACE("finished");
107 return TSS2_RC_SUCCESS;
108 }
109
110 /** Asynchronous function for Fapi_GetPlatformCertificates
111 *
112 * Platform certificates for TPM 2.0 can consist not only of a single certificate
113 * but a series of so-called delta certificates.
114 * This function returns the set of Platform certificates concatenated in
115 * a continuous buffer.
116 *
117 * Call Fapi_GetPlatformCertificates_Finish to finish the execution of this
118 * command.
119 *
120 * @param[in,out] context The FAPI_CONTEXT
121 *
122 * @retval TSS2_RC_SUCCESS: if the function call was a success.
123 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
124 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
125 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
126 * operation already pending.
127 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
128 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for internal
129 * operations or return parameters.
130 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
131 * config file.
132 */
133 TSS2_RC
134 Fapi_GetPlatformCertificates_Async(
135 FAPI_CONTEXT *context)
136 {
137 LOG_TRACE("called for context:%p", context);
138
139 TSS2_RC r;
140
141 /* Check for NULL parameters */
142 check_not_null(context);
143
144 /* Reset all context-internal session state information. */
145 r = ifapi_session_init(context);
146 return_if_error(r, "Initialize Fapi_GetPlatformCertificates");
147
148 /* Initialize the context state for this operation. */
149 context->state = GET_PLATFORM_CERTIFICATE;
150
151 LOG_TRACE("finished");
152 return TSS2_RC_SUCCESS;
153 }
154
155 /** Asynchronous finish function for Fapi_GetPlatformCertificates
156 *
157 * This function should be called after a previous
158 * Fapi_GetPlatformCertificates_Async.
159 *
160 * @param[in,out] context The FAPI_CONTEXT
161 * @param[out] certificates The platform certificates
162 * @param[out] certificatesSize The size of the buffer with the certificates.
163 * May be NULL
164 *
165 * @retval TSS2_RC_SUCCESS: if the function call was a success.
166 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or certificates is NULL.
167 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
168 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
169 * operation already pending.
170 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
171 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
172 * internal operations or return parameters.
173 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
174 * complete. Call this function again later.
175 * @retval TSS2_FAPI_RC_NO_CERT if an error did occur during certificate downloading.
176 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
177 * is not set.
178 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
179 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
180 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
181 * was not successful.
182 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
183 */
184 TSS2_RC
185 Fapi_GetPlatformCertificates_Finish(
186 FAPI_CONTEXT *context,
187 uint8_t **certificates,
188 size_t *certificatesSize)
189 {
190 LOG_TRACE("called for context:%p", context);
191
192 NODE_OBJECT_T *cert_list = NULL;
193 TSS2_RC r;
194
195 /* Check for NULL parameters */
196 check_not_null(context);
197 check_not_null(certificates);
198 *certificates = NULL;
199
200 switch (context->state) {
201 statecase(context->state, GET_PLATFORM_CERTIFICATE);
202 /* Retrieve the certificates from the TPM's NV space. */
203 r = ifapi_get_certificates(context, MIN_PLATFORM_CERT_HANDLE,
204 MAX_PLATFORM_CERT_HANDLE,
205 &cert_list);
206 return_try_again(r);
207 goto_if_error(r, "Get certificates.", error);
208
209 if (cert_list) {
210 /* Concatenate the found certificates */
211 size_t size;
212 NODE_OBJECT_T *cert = cert_list;
213 size = 0;
214 while (cert) {
215 size += cert->size;
216 cert = cert->next;
217 }
218 if (certificatesSize)
219 *certificatesSize = size;
220 *certificates = malloc(size);
221 goto_if_null2(*certificates, "Out of memory.",
222 r, TSS2_FAPI_RC_MEMORY, error);
223
224 cert = cert_list;
225 size = 0;
226 while (cert) {
227 memcpy(&cert[size], cert->object, cert->size);
228 size += cert->size;
229 cert = cert->next;
230 }
231 } else {
232 if (certificatesSize)
233 *certificatesSize = 0;
234 goto_error(r, TSS2_FAPI_RC_NO_CERT,
235 "No platform certificates available.", error);
236 }
237 break;
238 statecasedefault(context->state);
239 }
240
241 /* Cleanup any intermediate results and state stored in the context. */
242 ifapi_free_object_list(cert_list);
243 SAFE_FREE(context->cmd.Provision.capabilityData);
244 context->state = _FAPI_STATE_INIT;
245 LOG_TRACE("finished");
246 return TSS2_RC_SUCCESS;
247
248 error:
249 /* Cleanup any intermediate results and state stored in the context. */
250 context->state = _FAPI_STATE_INIT;
251 ifapi_free_object_list(cert_list);
252 SAFE_FREE(context->cmd.Provision.capabilityData);
253 SAFE_FREE(*certificates);
254 return r;
255 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14 #include "fapi_int.h"
15 #include "fapi_util.h"
16 #include "tss2_esys.h"
17 #define LOGMODULE fapi
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** Retrieve handles for polling
22 *
23 * Returns an array of handles that can be polled on to get notified when
24 * data from the TPM or from a disk operation is available.
25 *
26 * The corresponding code should look similar to follows:
27 * do { r = Fapi_GetPollHandles(fc, &ph, &nph);
28 if (r == TSS2_RC_SUCCESS) { poll(ph, nph, -1); Fapi_Free(ph); }
29 * r = Fapi_*_Finish(fc, ...); } while (r == TSS2_FAPI_RC_TRY_AGAIN);
30 *
31 * @param[in,out] context The FAPI_CONTEXT
32 * @param[out] handles An array of poll handle entries
33 * @param[out] num_handles The size of the array in handles
34 *
35 * @retval TSS2_RC_SUCCESS: if the function call was a success.
36 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or data is NULL.
37 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
38 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has no asynchronous
39 * operation pending.
40 * @retval TSS2_FAPI_RC_NO_HANDLE: if there are no handles to poll on
41 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
42 * internal operations or return parameters.
43 */
44 TSS2_RC
45 Fapi_GetPollHandles(
46 FAPI_CONTEXT *context,
47 FAPI_POLL_HANDLE **handles,
48 size_t *num_handles)
49 {
50 LOG_TRACE("called for context:%p", context);
51
52 TSS2_RC r;
53
54 /* Check for NULL parameters */
55 check_not_null(context);
56 check_not_null(handles);
57 check_not_null(num_handles);
58
59 /* Check the correct state for poll handle retrieval. */
60 if (context->state == _FAPI_STATE_INIT) {
61 LOG_ERROR("PollHandles can only be returned while an operation is running");
62 return TSS2_FAPI_RC_BAD_SEQUENCE;
63 }
64
65 /* First we check for poll handles from IO operations. */
66 r = ifapi_io_poll_handles(&context->io, handles, num_handles);
67 if (r == TSS2_RC_SUCCESS) {
68 LOG_DEBUG("Returning %zi IO poll handles.", *num_handles);
69 return r;
70 }
71 if (r != TSS2_FAPI_RC_NO_HANDLE)
72 return_if_error(r, "Retrieving poll handles failed");
73
74 /* Then we check for poll handles from ESYS operations. */
75 /* If we are running in none-TPM mode then we are already done trying. */
76 return_if_null(context->esys, "No non-TPM based poll handles found.",
77 TSS2_FAPI_RC_NO_HANDLE);
78
79 /* Retrieve the actual poll handles from ESYS. */
80 r = Esys_GetPollHandles(context->esys, handles, num_handles);
81 if (r) {
82 LOG_DEBUG("Returning TSS2_FAPI_RC_NO_HANDLE");
83 return TSS2_FAPI_RC_NO_HANDLE;
84 }
85
86 LOG_DEBUG("Returning %zi ESYS poll handles.", *num_handles);
87 LOG_TRACE("finished");
88 return r;
89 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14 #include "fapi_int.h"
15 #include "fapi_util.h"
16 #include "tss2_esys.h"
17 #define LOGMODULE fapi
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** One-Call function for Fapi_GetRandom
22 *
23 * Creates an array with a specified number of bytes. May execute the underlying
24 * TPM command multiple times if the requested number of bytes is too big.
25 *
26 * @param[in,out] context The FAPI_CONTEXT
27 * @param[in] numBytes The number of bytes requested from the TPM
28 * @param[out] data The array of random bytes returned from the TPM
29 *
30 * @retval TSS2_RC_SUCCESS: if the function call was a success.
31 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or data is NULL.
32 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
33 * @retval TSS2_FAPI_RC_BAD_VALUE: if numBytes is 0.
34 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
35 * operation already pending.
36 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
37 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
38 * internal operations or return parameters.
39 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
40 * config file.
41 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
42 * during authorization.
43 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
44 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
45 * this function needs to be called again.
46 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
47 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
48 * is not set.
49 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
50 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
51 * was not successful.
52 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
53 */
54 TSS2_RC
55 Fapi_GetRandom(
56 FAPI_CONTEXT *context,
57 size_t numBytes,
58 uint8_t **data)
59 {
60 LOG_TRACE("called for context:%p", context);
61
62 TSS2_RC r, r2;
63
64 /* Check for NULL parameters */
65 check_not_null(context);
66 check_not_null(data);
67
68 /* Check whether TCTI and ESYS are initialized */
69 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
70 TSS2_FAPI_RC_NO_TPM);
71
72 /* If the async state automata of FAPI shall be tested, then we must not set
73 the timeouts of ESYS to blocking mode.
74 During testing, the mssim tcti will ensure multiple re-invocations.
75 Usually however the synchronous invocations of FAPI shall instruct ESYS
76 to block until a result is available. */
77 #ifndef TEST_FAPI_ASYNC
78 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
79 return_if_error_reset_state(r, "Set Timeout to blocking");
80 #endif /* TEST_FAPI_ASYNC */
81
82 r = Fapi_GetRandom_Async(context, numBytes);
83 return_if_error_reset_state(r, "GetRandom");
84
85 do {
86 /* We wait for file I/O to be ready if the FAPI state automata
87 are in a file I/O state. */
88 r = ifapi_io_poll(&context->io);
89 return_if_error(r, "Something went wrong with IO polling");
90
91 /* Repeatedly call the finish function, until FAPI has transitioned
92 through all execution stages / states of this invocation. */
93 r = Fapi_GetRandom_Finish(context, data);
94 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
95
96 /* Reset the ESYS timeout to non-blocking, immediate response. */
97 r2 = Esys_SetTimeout(context->esys, 0);
98 return_if_error(r2, "Set Timeout to non-blocking");
99
100 return_if_error_reset_state(r, "GetRandom");
101
102 LOG_TRACE("finished");
103 return TSS2_RC_SUCCESS;
104 }
105
106 /** Asynchronous function for Fapi_GetRandom
107 *
108 * Creates an array with a specified number of bytes. May execute the underlying
109 * TPM command multiple times if the requested number of bytes is too big.
110 *
111 * Call Fapi_GetRandom_Finish to finish the execution of this command.
112 *
113 * @param[in,out] context The FAPI_CONTEXT
114 * @param[in] numBytes The number of bytes requested from the TPM
115 *
116 * @retval TSS2_RC_SUCCESS: if the function call was a success.
117 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
118 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
119 * @retval TSS2_FAPI_RC_BAD_VALUE: if numBytes is 0.
120 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
121 * operation already pending.
122 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
123 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
124 * internal operations or return parameters.
125 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
126 * config file.
127 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
128 * during authorization.
129 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
130 */
131 TSS2_RC
132 Fapi_GetRandom_Async(
133 FAPI_CONTEXT *context,
134 size_t numBytes)
135 {
136 LOG_TRACE("called for context:%p", context);
137 LOG_TRACE("numBytes: %zu", numBytes);
138
139 TSS2_RC r;
140
141 /* Check for NULL parameters */
142 check_not_null(context);
143
144 /* Helpful alias pointers */
145 IFAPI_GetRandom * command = &context->get_random;
146
147 /* Reset all context-internal session state information. */
148 r = ifapi_session_init(context);
149 return_if_error(r, "Initialize GetRandom");
150
151 /* Copy parameters to context for use during _Finish. */
152 command->numBytes = numBytes;
153 command->data = NULL;
154
155 /* Start a session for integrity protection and encryption of random data. */
156 r = ifapi_get_sessions_async(context,
157 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
158 TPMA_SESSION_ENCRYPT | TPMA_SESSION_DECRYPT, 0);
159 return_if_error_reset_state(r, "Create FAPI session");
160
161 /* Initialize the context state for this operation. */
162 context->state = GET_RANDOM_WAIT_FOR_SESSION;
163 LOG_TRACE("finished");
164 return TSS2_RC_SUCCESS;
165 }
166
167 /** Asynchronous finish function for Fapi_GetRandom
168 *
169 * This function should be called after a previous Fapi_GetRandom_Async.
170 *
171 * @param[in,out] context The FAPI_CONTEXT
172 * @param[out] data The array of random bytes returned from the TPM
173 *
174 * @retval TSS2_RC_SUCCESS: if the function call was a success.
175 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or data is NULL.
176 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
177 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
178 * operation already pending.
179 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
180 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
181 * internal operations or return parameters.
182 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
183 * complete. Call this function again later.
184 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
185 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
186 * the function.
187 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
188 * during authorization.
189 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
190 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
191 * is not set.
192 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
193 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
194 * was not successful.
195 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
196 */
197 TSS2_RC
198 Fapi_GetRandom_Finish(
199 FAPI_CONTEXT *context,
200 uint8_t **data)
201 {
202 LOG_TRACE("called for context:%p", context);
203
204 TSS2_RC r;
205
206 /* Check for NULL parameters */
207 check_not_null(context);
208 check_not_null(data);
209
210 /* Helpful alias pointers */
211 IFAPI_GetRandom * command = &context->get_random;
212
213 switch (context->state) {
214 statecase(context->state, GET_RANDOM_WAIT_FOR_SESSION);
215 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
216 context->profiles.default_profile.nameAlg);
217 return_try_again(r);
218 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
219
220 context->get_random_state = GET_RANDOM_INIT;
221
222 fallthrough;
223
224 statecase(context->state, GET_RANDOM_WAIT_FOR_RANDOM);
225 /* Retrieve the random data from the TPM.
226 This may involve several Esys_GetRandom calls. */
227 r = ifapi_get_random(context, command->numBytes, data);
228 return_try_again(r);
229 goto_if_error_reset_state(r, "FAPI GetRandom", error_cleanup);
230 fallthrough;
231
232 statecase(context->state, GET_RANDOM_CLEANUP)
233 /* Cleanup the session. */
234 r = ifapi_cleanup_session(context);
235 try_again_or_error_goto(r, "Cleanup", error_cleanup);
236
237 break;
238
239 statecasedefault(context->state);
240 }
241
242 /* Cleanup any intermediate results and state stored in the context. */
243 context->state = _FAPI_STATE_INIT;
244 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
245 ifapi_session_clean(context);
246 LOG_TRACE("finished");
247 return TSS2_RC_SUCCESS;
248
249 error_cleanup:
250 /* Cleanup any intermediate results and state stored in the context. */
251 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
252 ifapi_session_clean(context);
253 SAFE_FREE(context->get_random.data);
254 LOG_TRACE("finished");
255 return r;
256 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include "tss2_fapi.h"
11 #include "tss2_esys.h"
12 #include "tss2_tcti.h"
13
14 #include "fapi_int.h"
15 #define LOGMODULE fapi
16 #include "util/log.h"
17 #include "util/aux_util.h"
18
19 /** One-Call function for Fapi_GetTcti
20 *
21 * Fapi_GetTcti returns the TSS2_TCTI_CONTEXT currently used by the provided FAPI_CONTEXT.
22 * The purpose is to enable advanced access to the TPM that is currently being talked to.
23 * It is especially useful in combination with Fapi_GetTpmBlobs().
24 *
25 * Note: The application must ensure that this TSS2_TCTI_CONTEXT is not being used in parallel to
26 * the processing of a FAPI command.
27 *
28 * @param[in,out] context The FAPI_CONTEXT
29 * @param[out] tcti The TSS2_TCTI_CONTEXT used to talk to the current TPM.
30 *
31 * @retval TSS2_RC_SUCCESS: if the function call was a success.
32 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, tcti is NULL.
33 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
34 * @retval TSS2_FAPI_RC_NO_TPM: if FAPI was started in non-TPM mode.
35 */
36 TSS2_RC
37 Fapi_GetTcti(
38 FAPI_CONTEXT *context,
39 TSS2_TCTI_CONTEXT **tcti)
40 {
41 LOG_TRACE("called for context:%p", context);
42
43 TSS2_RC r;
44
45 /* Check for NULL parameters */
46 check_not_null(context);
47 check_not_null(tcti);
48
49 /* Check if FAPI was started in a non-TPM mode. */
50 if (!context->esys)
51 return_error(TSS2_FAPI_RC_NO_TPM, "Fapi is running in non-TPM mode");
52
53 /* Retrieve the TCTI from ESYS. */
54 r = Esys_GetTcti(context->esys, tcti);
55 return_if_error(r, "Esys_GetTcti");
56
57 LOG_DEBUG("finished");
58 return r;
59 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "tss2_mu.h"
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #include "ifapi_policy_json_serialize.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25
26 /** One-Call function for Fapi_GetTpmBlobs
27 *
28 * Get the public and private blobs of a TPM object. They can be loaded with a
29 * lower-level API such as the SAPI or the ESAPI.
30 *
31 * @param[in,out] context The FAPI_CONTEXT
32 * @param[in] path The path to the key for which the blobs will be returned
33 * @param[out] tpm2bPublic The returned public area of the object. May be NULL
34 * @param[out] tpm2bPublicSize The size of tpm2bPublic in bytes. May be NULL
35 * @param[out] tpm2bPrivate The returned private area of the object. May be
36 * NULL
37 * @param[out] tpm2bPrivateSize The size of tpm2bPrivate in bytes. May be NULL
38 * @param[out] policy The policy that is associated with the object encoded in
39 * JSON. May be NULL
40 *
41 * @retval TSS2_RC_SUCCESS: if the function call was a success.
42 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
43 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
44 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
45 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
46 * operation already pending.
47 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
48 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
49 * internal operations or return parameters.
50 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
51 * during authorization.
52 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
53 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
54 * the function.
55 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
56 * this function needs to be called again.
57 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
58 */
59 TSS2_RC
60 Fapi_GetTpmBlobs(
61 FAPI_CONTEXT *context,
62 char const *path,
63 uint8_t **tpm2bPublic,
64 size_t *tpm2bPublicSize,
65 uint8_t **tpm2bPrivate,
66 size_t *tpm2bPrivateSize,
67 char **policy)
68 {
69 LOG_TRACE("called for context:%p", context);
70
71 TSS2_RC r;
72
73 /* Check for NULL parameters */
74 check_not_null(context);
75 check_not_null(path);
76
77 r = Fapi_GetTpmBlobs_Async(context, path);
78 return_if_error_reset_state(r, "Entity_GetTPMBlobs");
79
80 do {
81 /* We wait for file I/O to be ready if the FAPI state automata
82 are in a file I/O state. */
83 r = ifapi_io_poll(&context->io);
84 return_if_error(r, "Something went wrong with IO polling");
85
86 /* Repeatedly call the finish function, until FAPI has transitioned
87 through all execution stages / states of this invocation. */
88 r = Fapi_GetTpmBlobs_Finish(context, tpm2bPublic, tpm2bPublicSize, tpm2bPrivate,
89 tpm2bPrivateSize, policy);
90 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
91
92 return_if_error_reset_state(r, "Entity_GetTPMBlobs");
93
94 LOG_TRACE("finished");
95 return TSS2_RC_SUCCESS;
96 }
97
98 /** Asynchronous function for Fapi_GetTpmBlobs
99 *
100 * Get the public and private blobs of a TPM object. They can be loaded with a
101 * lower-level API such as the SAPI or the ESAPI.
102 *
103 * Call Fapi_GetTpmBlobs_Finish to finish the execution of this command.
104 *
105 * @param[in,out] context The FAPI_CONTEXT
106 * @param[in] path The path to the key for which the blobs will be returned
107 *
108 * @retval TSS2_RC_SUCCESS: if the function call was a success.
109 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
110 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
111 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
112 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
113 * operation already pending.
114 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
115 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
116 * internal operations or return parameters.
117 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
118 * during authorization.
119 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
120 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
121 * the function.
122 */
123 TSS2_RC
124 Fapi_GetTpmBlobs_Async(
125 FAPI_CONTEXT *context,
126 char const *path)
127 {
128 LOG_TRACE("called for context:%p", context);
129 LOG_TRACE("path: %s", path);
130
131 TSS2_RC r;
132
133 /* Check for NULL parameters */
134 check_not_null(context);
135 check_not_null(path);
136
137 /* Load the object from the key store. */
138 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
139 return_if_error2(r, "Could not open: %s", path);
140
141 /* Initialize the context state for this operation. */
142 context->state = ENTITY_GET_TPM_BLOBS_READ;
143 LOG_TRACE("finished");
144 return TSS2_RC_SUCCESS;
145 }
146
147 /** Asynchronous finish function for Fapi_GetTpmBlobs
148 *
149 * This function should be called after a previous Fapi_GetTpmBlobs_Async.
150 *
151 * @param[in,out] context The FAPI_CONTEXT
152 * @param[out] tpm2bPublic The returned public area of the object. May be NULL
153 * @param[out] tpm2bPublicSize The size of tpm2bPublic in bytes. May be NULL
154 * @param[out] tpm2bPrivate The returned private area of the object. May be
155 * NULL
156 * @param[out] tpm2bPrivateSize The size of tpm2bPrivate in bytes. May be NULL
157 * @param[out] policy The policy that is associated with the object encoded in
158 * JSON. May be NULL
159 *
160 * @retval TSS2_RC_SUCCESS: if the function call was a success.
161 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
162 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
163 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
164 * operation already pending.
165 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
166 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
167 * internal operations or return parameters.
168 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
169 * complete. Call this function again later.
170 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
171 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
172 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
173 * the function.
174 */
175 TSS2_RC
176 Fapi_GetTpmBlobs_Finish(
177 FAPI_CONTEXT *context,
178 uint8_t **tpm2bPublic,
179 size_t *tpm2bPublicSize,
180 uint8_t **tpm2bPrivate,
181 size_t *tpm2bPrivateSize,
182 char **policy)
183 {
184 LOG_TRACE("called for context:%p", context);
185
186 TSS2_RC r;
187 IFAPI_OBJECT object;
188 UINT16 private_size;
189 size_t offset;
190 json_object *jso = NULL;
191
192 /* Check for NULL parameters */
193 check_not_null(context);
194
195 switch (context->state) {
196 statecase(context->state, ENTITY_GET_TPM_BLOBS_READ);
197 /* Finish readon the metadata from key store. */
198 r = ifapi_keystore_load_finish(&context->keystore, &context->io, &object);
199 return_try_again(r);
200 return_if_error_reset_state(r, "read_finish failed");
201
202 if (object.objectType != IFAPI_KEY_OBJ) {
203 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "No key object.", error_cleanup);
204 }
205
206 /* Marshal the public data to the output parameter. */
207 if (tpm2bPublic && tpm2bPublicSize) {
208 *tpm2bPublic = malloc(sizeof(uint8_t) * sizeof(TPM2B_PUBLIC));
209 goto_if_null(*tpm2bPublic, "Out of memory.",
210 TSS2_FAPI_RC_MEMORY, error_cleanup);
211 offset = 0;
212 r = Tss2_MU_TPM2B_PUBLIC_Marshal(&object.misc.key.public,
213 *tpm2bPublic, sizeof(TPM2B_PUBLIC), &offset);
214 goto_if_error_reset_state(r, "FAPI marshal TPM2B_PUBLIC",
215 error_cleanup);
216
217 *tpm2bPublicSize = offset;
218 goto_if_error(r, "Marshaling TPM2B_PUBLIC", error_cleanup);
219 }
220
221 /* Marshal the private data to the output parameter. */
222 if (tpm2bPrivate && tpm2bPrivateSize) {
223 private_size = object.misc.key.private.size;
224 *tpm2bPrivateSize = private_size + sizeof(UINT16);
225 *tpm2bPrivate = malloc(*tpm2bPrivateSize);
226 goto_if_null(*tpm2bPrivate, "Out of memory.",
227 TSS2_FAPI_RC_MEMORY, error_cleanup);
228 offset = 0;
229 r = Tss2_MU_UINT16_Marshal(private_size,
230 *tpm2bPrivate, sizeof(TPM2B_PRIVATE), &offset);
231 goto_if_error_reset_state(r, "FAPI marshal UINT16", error_cleanup);
232
233 memcpy(*tpm2bPrivate + offset, &object.misc.key.private.buffer[0], private_size);
234 }
235
236 /* Duplicate the policy to the output parameter. */
237 if (object.policy && policy) {
238 r = ifapi_json_TPMS_POLICY_serialize(
239 object.policy, &jso);
240 goto_if_error(r, "Serialize policy", error_cleanup);
241
242 strdup_check(*policy,
243 json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY),
244 r, error_cleanup);
245 json_object_put(jso);
246 }
247
248 /* Cleanup any intermediate results and state stored in the context. */
249 ifapi_cleanup_ifapi_object(&object);
250 context->state = _FAPI_STATE_INIT;
251 LOG_TRACE("finished");
252 return TSS2_RC_SUCCESS;
253
254 statecasedefault(context->state);
255 }
256 error_cleanup:
257 /* Cleanup any intermediate results and state stored in the context. */
258 if (jso)
259 json_object_put(jso);
260 ifapi_cleanup_ifapi_object(&object);
261 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
262 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
263 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
264 LOG_TRACE("finished");
265 return r;
266 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <libgen.h>
16
17 #include "tss2_fapi.h"
18 #include "fapi_int.h"
19 #include "fapi_util.h"
20 #include "tss2_esys.h"
21 #include "ifapi_json_deserialize.h"
22 #include "ifapi_policy_json_deserialize.h"
23 #include "tpm_json_deserialize.h"
24 #define LOGMODULE fapi
25 #include "util/log.h"
26 #include "util/aux_util.h"
27 #include "fapi_crypto.h"
28
29 /** One-Call function for Fapi_Import
30 *
31 * Imports a JSON encoded policy, policy template or key and stores it at the
32 * given path.
33 *
34 * @param[in,out] context The FAPI_CONTEXT
35 * @param[in] path the path to which the object is imported
36 * @param[in] importData The data that is imported
37 *
38 * @retval TSS2_RC_SUCCESS: if the function call was a success.
39 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, path or importData
40 * is NULL.
41 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
42 * @retval TSS2_FAPI_RC_BAD_PATH: If path does not map to a FAPI policy or key.
43 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a policy or key already exists
44 * at path.
45 * @retval TSS2_FAPI_RC_BAD_VALUE: if importData contains invalid data.
46 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
47 * operation already pending.
48 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
49 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
50 * internal operations or return parameters.
51 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
52 * config file.
53 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
54 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
55 * this function needs to be called again.
56 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
57 * during authorization.
58 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
59 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
60 * is not set.
61 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
62 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
63 * was not successful.
64 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
65 */
66 TSS2_RC
67 Fapi_Import(
68 FAPI_CONTEXT *context,
69 char const *path,
70 char const *importData)
71 {
72 LOG_TRACE("called for context:%p", context);
73
74 TSS2_RC r;
75
76 /* Check for NULL parameters */
77 check_not_null(context);
78 check_not_null(path);
79 check_not_null(importData);
80
81 r = Fapi_Import_Async(context, path, importData);
82 return_if_error_reset_state(r, "Entity_Import");
83
84 do {
85 /* We wait for file I/O to be ready if the FAPI state automata
86 are in a file I/O state. */
87 r = ifapi_io_poll(&context->io);
88 return_if_error(r, "Something went wrong with IO polling");
89
90 /* Repeatedly call the finish function, until FAPI has transitioned
91 through all execution stages / states of this invocation. */
92 r = Fapi_Import_Finish(context);
93 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
94
95 return_if_error_reset_state(r, "Entity_Import");
96
97 LOG_TRACE("finished");
98 return TSS2_RC_SUCCESS;
99 }
100
101 /** Asynchronous function for Fapi_Import
102 *
103 * Imports a JSON encoded policy, policy template or key and stores it at the
104 * given path.
105 *
106 * Call Fapi_Import_Finish to finish the execution of this command.
107 *
108 * @param[in,out] context The FAPI_CONTEXT
109 * @param[in] path the path to which the object is imported
110 * @param[in] importData The data that is imported
111 *
112 * @retval TSS2_RC_SUCCESS: if the function call was a success.
113 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, path or importData
114 * is NULL.
115 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
116 * @retval TSS2_FAPI_RC_BAD_PATH: If path does not map to a FAPI policy or key.
117 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if a policy or key already exists
118 * at path.
119 * @retval TSS2_FAPI_RC_BAD_VALUE: if importData contains invalid data.
120 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
121 * operation already pending.
122 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
123 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
124 * internal operations or return parameters.
125 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
126 * config file.
127 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
128 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
129 */
130 TSS2_RC
131 Fapi_Import_Async(
132 FAPI_CONTEXT *context,
133 char const *path,
134 char const *importData)
135 {
136 LOG_TRACE("called for context:%p", context);
137 LOG_TRACE("path: %s", path);
138 LOG_TRACE("importData: %s", importData);
139
140 TSS2_RC r;
141 json_object *jso = NULL;
142 json_object *jso2;
143 size_t pos = 0;
144 TPMS_POLICY policy = { 0 };
145
146 /* Check for NULL parameters */
147 check_not_null(context);
148 check_not_null(path);
149 check_not_null(importData);
150
151 /* Helpful alias pointers */
152 IFAPI_ImportKey * command = &context->cmd.ImportKey;
153 IFAPI_OBJECT *object = &command->object;
154 IFAPI_EXT_PUB_KEY * extPubKey = &object->misc.ext_pub_key;
155 IFAPI_DUPLICATE * keyTree = &object->misc.key_tree;
156
157 if (context->state != _FAPI_STATE_INIT) {
158 return_error(TSS2_FAPI_RC_BAD_SEQUENCE, "Invalid State");
159 }
160
161 command->jso_string = NULL;
162 strdup_check(command->out_path, path, r, cleanup_error);
163 memset(&command->object, 0, sizeof(IFAPI_OBJECT));
164 extPubKey->pem_ext_public = NULL;
165
166 if (strncmp(importData, IFAPI_PEM_PUBLIC_STRING,
167 sizeof(IFAPI_PEM_PUBLIC_STRING) - 1) == 0) {
168 object->objectType = IFAPI_EXT_PUB_KEY_OBJ;
169 strdup_check(extPubKey->pem_ext_public, importData, r, cleanup_error);
170 extPubKey->certificate = NULL;
171
172 TPM2_ALG_ID rsaOrEcc = ifapi_get_signature_algorithm_from_pem(
173 extPubKey->pem_ext_public);
174 r = ifapi_initialize_sign_public(rsaOrEcc, &extPubKey->public);
175 goto_if_error(r, "Could not initialize key template", cleanup_error);
176
177 r = ifapi_get_tpm2b_public_from_pem(extPubKey->pem_ext_public,
178 &extPubKey->public);
179 goto_if_error(r, "Convert PEM public key into TPM public key.", cleanup_error);
180
181 command->new_object = *object;
182 if (strncmp("/", path, 1) == 0)
183 pos = 1;
184 if (strncmp(&path[pos], IFAPI_PUB_KEY_DIR, strlen(IFAPI_PUB_KEY_DIR)) != 0) {
185 SAFE_FREE(command->out_path);
186 r = ifapi_asprintf(&command->out_path,
187 "%s%s%s", IFAPI_PUB_KEY_DIR, IFAPI_FILE_DELIM,
188 &path[pos]);
189 goto_if_error(r, "Allocate path name", cleanup_error);
190
191 }
192 r = ifapi_non_tpm_mode_init(context);
193 return_if_error(r, "Initialize Import in none TPM mode");
194
195 context->state = IMPORT_KEY_WRITE_OBJECT_PREPARE;
196
197 } else if (strcmp(importData, IFAPI_PEM_PRIVATE_KEY) == 0) {
198 return_error(TSS2_FAPI_RC_BAD_VALUE, "Invalid import data");
199
200 } else {
201 /* Check whether TCTI and ESYS are initialized */
202 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
203 TSS2_FAPI_RC_NO_TPM);
204
205 /* If the async state automata of FAPI shall be tested, then we must not set
206 the timeouts of ESYS to blocking mode.
207 During testing, the mssim tcti will ensure multiple re-invocations.
208 Usually however the synchronous invocations of FAPI shall instruct ESYS
209 to block until a result is available. */
210 #ifndef TEST_FAPI_ASYNC
211 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
212 return_if_error_reset_state(r, "Set Timeout to blocking");
213 #endif /* TEST_FAPI_ASYNC */
214
215 r = ifapi_session_init(context);
216 return_if_error(r, "Initialize Import");
217
218 /* Otherwise a JSON object has to be checked whether a key or policy is passed */
219 jso = json_tokener_parse(importData);
220 return_if_null(jso, "Json error.", TSS2_FAPI_RC_BAD_VALUE);
221
222 if (ifapi_get_sub_object(jso, IFAPI_JSON_TAG_POLICY, &jso2) &&
223 !(ifapi_get_sub_object(jso, IFAPI_JSON_TAG_DUPLICATE, &jso2))
224 ) {
225 /* Create policy object */
226 r = ifapi_json_TPMS_POLICY_deserialize(jso, &policy);
227 goto_if_error(r, "Serialize policy", cleanup_error);
228
229 r = ifapi_policy_store_store_async(&context->pstore, &context->io,
230 command->out_path, &policy);
231 goto_if_error_reset_state(r, "Could not open: %s", cleanup_error,
232 command->out_path);
233
234 ifapi_cleanup_policy(&policy);
235
236 context->state = IMPORT_KEY_WRITE_POLICY;
237
238 r = TSS2_RC_SUCCESS;
239 } else {
240 /* Write key object */
241 r = ifapi_json_IFAPI_OBJECT_deserialize(jso, object);
242 goto_if_error(r, "Invalid object.", cleanup_error);
243
244 switch (object->objectType) {
245 case IFAPI_EXT_PUB_KEY_OBJ:
246 /* Write json string stored in importData */
247 /* Start writing the EK to the key store */
248 r = ifapi_keystore_store_async(&context->keystore, &context->io,
249 command->out_path, object);
250 goto_if_error_reset_state(r, "Could not open: %sh", cleanup_error,
251 command->out_path);
252
253 context->state = IMPORT_KEY_WRITE;
254 break;
255
256 case IFAPI_DUPLICATE_OBJ:
257 r = ifapi_get_name(
258 &keyTree->public_parent.publicArea,
259 &command->parent_name);
260 goto_if_error2(r, "Get parent name", cleanup_error);
261
262 context->state = IMPORT_KEY_SEARCH;
263 break;
264
265 default:
266 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid object type",
267 cleanup_error);
268 break;
269 }
270 command->parent_path = NULL;
271 }
272 }
273 json_object_put(jso);
274 LOG_TRACE("finished");
275 return r;
276
277 cleanup_error:
278 if (jso)
279 json_object_put(jso);
280 context->state = _FAPI_STATE_INIT;
281 ifapi_cleanup_policy(&policy);
282 SAFE_FREE(command->jso_string);
283 SAFE_FREE(extPubKey->pem_ext_public);
284 SAFE_FREE(command->out_path);
285 return r;
286 }
287
288 /** Asynchronous finish function for Fapi_Import_
289 *
290 * This function should be called after a previous Fapi_Import_Async.
291 *
292 * @param[in,out] context The FAPI_CONTEXT
293 *
294 * @retval TSS2_RC_SUCCESS: if the function call was a success.
295 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
296 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
297 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
298 * operation already pending.
299 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
300 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
301 * internal operations or return parameters.
302 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
303 * complete. Call this function again later.
304 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
305 * during authorization.
306 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
307 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
308 * the function.
309 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
310 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
311 * is not set.
312 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
313 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
314 * was not successful.
315 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
316 */
317 TSS2_RC
318 Fapi_Import_Finish(
319 FAPI_CONTEXT *context)
320 {
321 LOG_TRACE("called for context:%p", context);
322
323 TSS2_RC r;
324 ESYS_TR session;
325
326 /* Check for NULL parameters */
327 check_not_null(context);
328
329 /* Helpful alias pointers */
330 IFAPI_ImportKey * command = &context->cmd.ImportKey;
331 IFAPI_OBJECT *newObject = &command->new_object;
332 IFAPI_OBJECT *object = &command->object;
333 IFAPI_DUPLICATE * keyTree = &object->misc.key_tree;
334
335 switch (context->state) {
336 statecase(context->state, IMPORT_KEY_WRITE_POLICY);
337 r = ifapi_policy_store_store_finish(&context->pstore, &context->io);
338 return_try_again(r);
339 return_if_error_reset_state(r, "write_finish failed");
340
341 context->state = _FAPI_STATE_INIT;
342 break;
343
344 statecase(context->state, IMPORT_KEY_WRITE);
345 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
346 return_try_again(r);
347 return_if_error_reset_state(r, "write_finish failed");
348
349 context->state = _FAPI_STATE_INIT;
350 break;
351
352 statecase(context->state, IMPORT_KEY_SEARCH);
353 r = ifapi_keystore_search_obj(&context->keystore, &context->io,
354 &command->parent_name,
355 &command->parent_path);
356 return_try_again(r);
357 goto_if_error(r, "Search Key", error_cleanup);
358
359 context->state = IMPORT_KEY_LOAD_PARENT;
360 fallthrough;
361
362 statecase(context->state, IMPORT_KEY_LOAD_PARENT);
363 r = ifapi_load_key(context, command->parent_path,
364 &command->parent_object);
365 return_try_again(r);
366 goto_if_error(r, "Fapi load key.", error_cleanup);
367
368 context->state = IMPORT_KEY_AUTHORIZE_PARENT;
369 fallthrough;
370
371 statecase(context->state, IMPORT_KEY_AUTHORIZE_PARENT);
372 r = ifapi_authorize_object(context, command->parent_object, &session);
373 return_try_again(r);
374 goto_if_error(r, "Authorize key.", error_cleanup);
375
376 TPMT_SYM_DEF_OBJECT symmetric;
377 symmetric.algorithm = TPM2_ALG_NULL;
378 r = Esys_Import_Async(context->esys,
379 command->parent_object->handle,
380 session,
381 ESYS_TR_NONE, ESYS_TR_NONE,
382 NULL, &keyTree->public,
383 &keyTree->duplicate,
384 &keyTree->encrypted_seed,
385 &symmetric);
386 goto_if_error(r, "Import Async", error_cleanup);
387
388 context->state = IMPORT_KEY_IMPORT;
389 fallthrough;
390
391 statecase(context->state, IMPORT_KEY_IMPORT);
392 r = Esys_Import_Finish(context->esys, &command->private);
393 try_again_or_error_goto(r, "Import", error_cleanup);
394
395 context->state = IMPORT_KEY_WAIT_FOR_FLUSH;
396 fallthrough;
397
398 statecase(context->state, IMPORT_KEY_WAIT_FOR_FLUSH);
399 r = ifapi_flush_object(context, command->parent_object->handle);
400 ifapi_cleanup_ifapi_object(command->parent_object);
401 return_try_again(r);
402 goto_if_error(r, "Flush key", error_cleanup);
403
404 memset(newObject, 0, sizeof(IFAPI_OBJECT));
405 newObject->objectType = IFAPI_KEY_OBJ;
406 newObject->misc.key.public = keyTree->public;
407 newObject->policy = keyTree->policy;
408 newObject->misc.key.private.size = command->private->size;
409 newObject->misc.key.private.buffer = &command->private->buffer[0];
410 newObject->misc.key.policyInstance = NULL;
411 newObject->misc.key.description = NULL;
412 newObject->misc.key.certificate = NULL;
413 r = ifapi_get_profile_sig_scheme(&context->profiles.default_profile,
414 &keyTree->public.publicArea,
415 &newObject->misc.key.signing_scheme);
416 goto_if_error(r, "Get signing scheme.", error_cleanup);
417 fallthrough;
418
419 statecase(context->state, IMPORT_KEY_WRITE_OBJECT_PREPARE);
420 /* Perform esys serialization if necessary */
421 r = ifapi_esys_serialize_object(context->esys, newObject);
422 goto_if_error(r, "Prepare serialization", error_cleanup);
423
424 /* Start writing the NV object to the key store */
425 r = ifapi_keystore_store_async(&context->keystore, &context->io,
426 command->out_path,
427 newObject);
428 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
429 context->nv_cmd.nvPath);
430
431 context->state = IMPORT_KEY_WRITE_OBJECT;
432 fallthrough;
433
434 statecase(context->state, IMPORT_KEY_WRITE_OBJECT);
435 /* Finish writing the object to the key store */
436 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
437 return_try_again(r);
438 return_if_error_reset_state(r, "write_finish failed");
439
440 fallthrough;
441
442 statecase(context->state, IMPORT_KEY_CLEANUP)
443 r = ifapi_cleanup_session(context);
444 try_again_or_error_goto(r, "Cleanup", error_cleanup);
445
446 break;
447
448 statecasedefault(context->state);
449 }
450
451 /* Reset the ESYS timeout to non-blocking, immediate response. */
452 if (context->esys) {
453 r = Esys_SetTimeout(context->esys, 0);
454 goto_if_error(r, "Set Timeout to non-blocking", error_cleanup);
455 }
456
457 context->state = _FAPI_STATE_INIT;
458 SAFE_FREE(command->out_path);
459
460 /* Cleanup policy for key objects.*/
461 if (newObject->objectType == IFAPI_KEY_OBJ) {
462 if (newObject->policy)
463 ifapi_cleanup_policy(newObject->policy);
464 SAFE_FREE(newObject->policy);
465 }
466 SAFE_FREE(command->parent_path);
467 ifapi_cleanup_ifapi_object(&command->object);
468 SAFE_FREE(command->private);
469 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
470 if (context->loadKey.key_object){
471 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
472 }
473 LOG_TRACE("finished");
474 return TSS2_RC_SUCCESS;
475
476 error_cleanup:
477 if (newObject)
478 ifapi_cleanup_ifapi_object(newObject);
479 SAFE_FREE(command->out_path);
480 SAFE_FREE(command->parent_path);
481 ifapi_cleanup_ifapi_object(&command->object);
482 SAFE_FREE(command->private);
483 Esys_SetTimeout(context->esys, 0);
484 ifapi_session_clean(context);
485 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
486 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
487 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
488 return r;
489 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #ifndef NO_DL
15 #include <dlfcn.h>
16 #endif /* NO_DL */
17
18 #include "tss2_tcti.h"
19 #include "tss2_tctildr.h"
20 #include "tss2_esys.h"
21 #include "tss2_fapi.h"
22 #include "fapi_int.h"
23 #include "fapi_util.h"
24 #include "ifapi_json_deserialize.h"
25 #define LOGMODULE fapi
26 #include "util/log.h"
27 #include "util/aux_util.h"
28
29 /** One-Call function for Fapi_Initialize
30 *
31 * Initializes a FAPI_CONTEXT that holds all the state and metadata information
32 * during an interaction with the TPM.
33 *
34 * @param[out] context The FAPI_CONTEXT
35 * @param[in] uri Unused in this version of the FAPI. Must be NULL
36 *
37 * @retval TSS2_RC_SUCCESS: if the function call was a success.
38 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
39 * @retval TSS2_FAPI_RC_BAD_VALUE: if uri is not NULL.
40 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
41 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
42 * internal operations or return parameters.
43 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
44 * this function needs to be called again.
45 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
46 * operation already pending.
47 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
48 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
49 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
50 */
51 TSS2_RC
52 Fapi_Initialize(
53 FAPI_CONTEXT **context,
54 char const *uri)
55 {
56 LOG_TRACE("called for context:%p", context);
57
58 TSS2_RC r = TSS2_RC_SUCCESS;
59
60 /* Check for NULL parameters */
61 check_not_null(context);
62 if (uri != NULL) {
63 LOG_ERROR("uri is not NULL");
64 return TSS2_FAPI_RC_BAD_VALUE;
65 }
66
67 r = Fapi_Initialize_Async(context, uri);
68 return_if_error(r, "FAPI Async call initialize");
69 check_oom(*context);
70
71 do {
72 /* We wait for file I/O to be ready if the FAPI state automata
73 are in a file I/O state. */
74 r = ifapi_io_poll(&(*context)->io);
75 return_if_error(r, "Something went wrong with IO polling");
76
77 /* Repeatedly call the finish function, until FAPI has transitioned
78 through all execution stages / states of this invocation. */
79 r = Fapi_Initialize_Finish(context);
80 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
81
82 LOG_TRACE("finished");
83 return r;
84 }
85
86 /** Asynchronous function for Fapi_Initialize
87 *
88 * Initializes a FAPI_CONTEXT that holds all the state and metadata information
89 * during an interaction with the TPM.
90 *
91 * Call Fapi_Initialize to finish the execution of this command.
92 *
93 * @param[out] context The FAPI_CONTEXT
94 * @param[in] uri Unused in this version of the FAPI. Must be NULL
95 *
96 * @retval TSS2_RC_SUCCESS: if the function call was a success.
97 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
98 * @retval TSS2_FAPI_RC_BAD_VALUE: if uri is not NULL.
99 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
100 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
101 * internal operations or return parameters.
102 */
103 TSS2_RC
104 Fapi_Initialize_Async(
105 FAPI_CONTEXT **context,
106 char const *uri)
107 {
108 LOG_TRACE("called for context:%p", context);
109 LOG_TRACE("uri: %s", uri);
110
111 TSS2_RC r = TSS2_RC_SUCCESS;
112
113 /* Check for NULL parameters */
114 check_not_null(context);
115 if (uri != NULL) {
116 LOG_ERROR("uri is not NULL");
117 return TSS2_FAPI_RC_BAD_VALUE;
118 }
119
120 *context = NULL;
121
122 /* Allocate memory for the FAPI context
123 * After this errors must jump to cleanup_return instead of returning. */
124 *context = calloc(1, sizeof(FAPI_CONTEXT));
125 return_if_null(*context, "Out of memory.", TSS2_FAPI_RC_MEMORY);
126 memset(*context, 0, sizeof(FAPI_CONTEXT));
127
128 /* Initialize the context */
129 r = ifapi_config_initialize_async(&(*context)->io);
130 goto_if_error(r, "Could not initialize FAPI context", cleanup_return);
131
132 /* Initialize the context state for this operation. */
133 (*context)->state = INITIALIZE_READ;
134
135 cleanup_return:
136 if (r)
137 SAFE_FREE(*context);
138 LOG_TRACE("finished");
139 return r;
140 }
141
142 /** Asynchronous finish function for Fapi_Initialize
143 *
144 * This function should be called after a previous Fapi_Initialize_Async.
145 *
146 * @param[out] context The FAPI_CONTEXT
147 *
148 * @retval TSS2_RC_SUCCESS: if the function call was a success.
149 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
150 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
151 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
152 * operation already pending.
153 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
154 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
155 * internal operations or return parameters.
156 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
157 * complete. Call this function again later.
158 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
159 * the function.
160 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
161 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
162 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
163 */
164 TSS2_RC
165 Fapi_Initialize_Finish(
166 FAPI_CONTEXT **context)
167 {
168 LOG_TRACE("called for context:%p", context);
169
170 TSS2_RC r;
171 TPMI_YES_NO moreData;
172 TSS2_TCTI_CONTEXT *fapi_tcti = NULL;
173
174 /* Check for NULL parameters */
175 check_not_null(context);
176 check_not_null(*context);
177
178 /* Helpful alias pointers */
179 TPMS_CAPABILITY_DATA **capability = &(*context)->cmd.Initialize.capability;
180
181 switch ((*context)->state) {
182 statecase((*context)->state, INITIALIZE_READ);
183 /* This is the entry point; finishing the initialization of the config module. */
184 r = ifapi_config_initialize_finish(&(*context)->io, &(*context)->config);
185 return_try_again(r);
186 goto_if_error(r, "Could not finish initialization", cleanup_return);
187
188 /* Initialize the event log module. */
189 r = ifapi_eventlog_initialize(&((*context)->eventlog), (*context)->config.log_dir);
190 goto_if_error(r, "Initializing evenlog module", cleanup_return);
191
192 /* Initialize the keystore. */
193 r = ifapi_keystore_initialize(&((*context)->keystore),
194 (*context)->config.keystore_dir,
195 (*context)->config.user_dir,
196 (*context)->config.profile_name);
197 goto_if_error2(r, "Keystore could not be initialized.", cleanup_return);
198
199 /* Initialize the policy store. */
200 /* Policy directory will be placed in keystore dir */
201 r = ifapi_policy_store_initialize(&((*context)->pstore),
202 (*context)->config.keystore_dir);
203 goto_if_error2(r, "Keystore could not be initialized.", cleanup_return);
204
205 fallthrough;
206
207 statecase((*context)->state, INITIALIZE_INIT_TCTI);
208 if (strcasecmp((*context)->config.tcti, "none") == 0) {
209 /* FAPI will be used in none TPM mode */
210 (*context)->esys = NULL;
211 (*context)->state = INITIALIZE_READ_PROFILE_INIT;
212 return TSS2_FAPI_RC_TRY_AGAIN;
213 }
214
215 /* Call for the TctiLdr to initialize a TCTI context given the config
216 from the FAPI config module. */
217 r = Tss2_TctiLdr_Initialize((*context)->config.tcti, &fapi_tcti);
218 goto_if_error(r, "Initializing TCTI.", cleanup_return);
219
220 /* Initialize an ESYS context using this Tcti. */
221 r = Esys_Initialize(&((*context)->esys), fapi_tcti, NULL);
222 goto_if_error(r, "Initialize esys context.", cleanup_return);
223
224 /* Call Startup on the TPM. */
225 r = Esys_Startup((*context)->esys, TPM2_SU_CLEAR);
226 if (r != TSS2_RC_SUCCESS && r != TPM2_RC_INITIALIZE) {
227 LOG_ERROR("Esys_Startup FAILED! Response Code : 0x%x", r);
228 return r;
229 }
230 fallthrough;
231
232 statecase((*context)->state, INITIALIZE_GET_CAP);
233 /* Retrieve the maximal value for transfer of nv data from the TPM. */
234 r = Esys_GetCapability_Async((*context)->esys, ESYS_TR_NONE, ESYS_TR_NONE,
235 ESYS_TR_NONE,
236 TPM2_CAP_TPM_PROPERTIES, TPM2_PT_NV_BUFFER_MAX, 1);
237 goto_if_error(r, "Error json deserialize", cleanup_return);
238
239 fallthrough;
240
241 statecase((*context)->state, INITIALIZE_WAIT_FOR_CAP);
242 r = Esys_GetCapability_Finish((*context)->esys, &moreData, capability);
243 return_try_again(r);
244 goto_if_error(r, "Get capability data.", cleanup_return);
245
246 /* Check if the TPM returns the NV_BUFFER_MAX value. */
247 if ((*capability)->data.tpmProperties.count == 1 &&
248 (*capability)->data.tpmProperties.tpmProperty[0].property ==
249 TPM2_PT_NV_BUFFER_MAX) {
250 (*context)->nv_buffer_max = (*capability)->data.tpmProperties.tpmProperty[0].value;
251 /* FAPI also contains an upper limit on the NV_MAX_BUFFER size. This is
252 useful for vTPMs that could in theory allow for several Megabytes of
253 max transfer buffer sizes. */
254 if ((*context)->nv_buffer_max > IFAPI_MAX_BUFFER_SIZE)
255 (*context)->nv_buffer_max = IFAPI_MAX_BUFFER_SIZE;
256 } else {
257 /* Note that for some time it was legal for a TPM to not return this value.
258 in that case FAPI falls back to 64 bytes for NV_BUFFER_MAX that all TPMs
259 must support. This slows down communication for NV read and write but
260 ensures that data can be exchanged with the TPM. */
261 (*context)->nv_buffer_max = 64;
262 }
263 fallthrough;
264
265 statecase((*context)->state, INITIALIZE_READ_PROFILE_INIT);
266 /* Initialize the proviles module that loads cryptographic profiles.
267 The default profile is taken from config. */
268 r = ifapi_profiles_initialize_async(&(*context)->profiles, &(*context)->io,
269 (*context)->config.profile_dir,
270 (*context)->config.profile_name);
271 return_if_error(r, "Read profile");
272
273 fallthrough;
274
275 statecase((*context)->state, INITIALIZE_READ_PROFILE);
276 r = ifapi_profiles_initialize_finish(&(*context)->profiles, &(*context)->io);
277 FAPI_SYNC(r, "Read profile.", cleanup_return);
278
279 LOG_DEBUG("success: *context %p", *context);
280 break;
281
282 statecasedefault((*context)->state);
283 }
284
285 (*context)->state = _FAPI_STATE_INIT;
286 SAFE_FREE(*capability);
287 LOG_TRACE("finished");
288 return TSS2_RC_SUCCESS;
289
290 cleanup_return:
291 /* Cleanup any intermediate results and state stored in the context. */
292 if ((*context)->esys) {
293 Esys_GetTcti((*context)->esys, &fapi_tcti);
294 Esys_Finalize(&(*context)->esys);
295 }
296 if (fapi_tcti) {
297 Tss2_TctiLdr_Finalize(&fapi_tcti);
298 }
299
300 /* Free the context memory in case of an error. */
301 free(*context);
302 *context = NULL;
303
304 return r;
305 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <dirent.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #include "ifapi_keystore.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 /** One-Call function for Fapi_List
26 *
27 * Enumerates all objects in the metadatastore in a fiven path and returns them
28 * in a list of complete paths from the root with the values separated by
29 * colons.
30 *
31 * @param[in,out] context The FAPI_CONTEXT
32 * @param[in] searchPath The path that identifies the root of the search
33 * @param[out] pathList A colon-separated list of all objects in the root path
34 *
35 * @retval TSS2_RC_SUCCESS: if the function call was a success.
36 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, searchPath, pathlist is
37 * NULL.
38 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
39 * @retval TSS2_FAPI_RC_BAD_PATH: if searchPath does not map to a FAPI entity.
40 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
41 * operation already pending.
42 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
43 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
44 * internal operations or return parameters.
45 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
46 * during authorization.
47 */
48 TSS2_RC
49 Fapi_List(
50 FAPI_CONTEXT *context,
51 char const *searchPath,
52 char **pathList)
53 {
54 LOG_TRACE("called for context:%p", context);
55
56 TSS2_RC r;
57
58 /* Check for NULL parameters */
59 check_not_null(context);
60 check_not_null(searchPath);
61 check_not_null(pathList);
62
63 r = Fapi_List_Async(context, searchPath);
64 return_if_error_reset_state(r, "Entities_List");
65
66 do {
67 /* We wait for file I/O to be ready if the FAPI state automata
68 are in a file I/O state. */
69 r = ifapi_io_poll(&context->io);
70 return_if_error(r, "Something went wrong with IO polling");
71
72 /* Repeatedly call the finish function, until FAPI has transitioned
73 through all execution stages / states of this invocation. */
74 r = Fapi_List_Finish(context, pathList);
75 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
76
77 return_if_error_reset_state(r, "Entities_List");
78
79 LOG_TRACE("finished");
80 return TSS2_RC_SUCCESS;
81 }
82
83 /** Asynchronous function for Fapi_List
84 *
85 * Enumerates all objects in the metadatastore in a fiven path and returns them
86 * in a list of complete paths from the root with the values separated by
87 * colons.
88 *
89 * Call Fapi_List_Finish to finish the execution of this command.
90 *
91 * @retval TSS2_RC_SUCCESS: if the function call was a success.
92 * @param[in,out] context The FAPI_CONTEXT
93 * @param[in] searchPath The path that identifies the root of the search
94 *
95 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or searchPath is
96 * NULL.
97 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
98 * @retval TSS2_FAPI_RC_BAD_PATH: if searchPath does not map to a FAPI entity.
99 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
100 * operation already pending.
101 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
102 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
103 * internal operations or return parameters.
104 */
105 TSS2_RC
106 Fapi_List_Async(
107 FAPI_CONTEXT *context,
108 char const *searchPath)
109 {
110 LOG_TRACE("called for context:%p", context);
111 LOG_TRACE("searchPath: %s", searchPath);
112
113 TSS2_RC r;
114
115 /* Check for NULL parameters */
116 check_not_null(context);
117 check_not_null(searchPath);
118
119 /* Helpful alias pointers */
120 IFAPI_Entities_List * command = &context->cmd.Entities_List;
121
122 r = ifapi_non_tpm_mode_init(context);
123 return_if_error(r, "Initialize List");
124
125 /* Copy parameters to context for use during _Finish. */
126 strdup_check(command->searchPath, searchPath, r, error_cleanup);
127
128 LOG_TRACE("finished");
129 return TSS2_RC_SUCCESS;
130
131 error_cleanup:
132 /* Cleanup duplicated input parameters that were copied before. */
133 SAFE_FREE(command->searchPath);
134 return r;
135 }
136
137 /** Asynchronous finish function for Fapi_List
138 *
139 * This function should be called after a previous Fapi_List_Async.
140 *
141 * @param[in,out] context The FAPI_CONTEXT
142 * @param[out] pathList A colon-separated list of all objects in the root path
143 *
144 * @retval TSS2_RC_SUCCESS: if the function call was a success.
145 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or pathList is NULL.
146 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
147 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
148 * operation already pending.
149 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
150 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
151 * internal operations or return parameters.
152 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
153 * complete. Call this function again later.
154 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
155 * during authorization.
156 */
157 TSS2_RC
158 Fapi_List_Finish(
159 FAPI_CONTEXT *context,
160 char **pathList)
161 {
162 LOG_TRACE("called for context:%p", context);
163
164 TSS2_RC r = TSS2_RC_SUCCESS;
165 size_t sizePathList = 0;
166 size_t numPaths = 0;
167 char **pathArray = NULL;
168
169 /* Check for NULL parameters */
170 check_not_null(context);
171 check_not_null(pathList);
172
173 /* Helpful alias pointers */
174 IFAPI_Entities_List * command = &context->cmd.Entities_List;
175
176 /* Retrieve the objects along the search path. */
177 r = ifapi_keystore_list_all(&context->keystore, command->searchPath,
178 &pathArray, &numPaths);
179 goto_if_error(r, "get entities.", cleanup);
180
181 if (numPaths == 0)
182 goto cleanup;
183
184 /* Determine size of char string to be returnded */
185 for (size_t i = 0; i < numPaths; i++)
186 sizePathList += strlen(pathArray[i]);
187
188 /* Allocate path list plus colon separators plus \0-terminator */
189 *pathList = malloc(sizePathList + (numPaths - 1) + 1);
190 goto_if_null2(*pathList, "Out of memory", r, TSS2_FAPI_RC_MEMORY, cleanup);
191
192 (*pathList)[0] = '\0';
193 (*pathList)[sizePathList + numPaths - 1] = '\0';
194
195 /* Concatenate the path entries to the output string. */
196 for (size_t i = 0; i < numPaths; i++) {
197 strcat(*pathList, pathArray[i]);
198 if (i < numPaths - 1)
199 strcat(*pathList, IFAPI_LIST_DELIM);
200 }
201
202 LOG_TRACE("finished");
203
204 cleanup:
205 /* Cleanup any intermediate results and state stored in the context. */
206 SAFE_FREE(command->searchPath);
207 if (numPaths == 0 && (r == TSS2_RC_SUCCESS)) {
208 LOG_ERROR("Path not found: %s", command->searchPath);
209 r = TSS2_FAPI_RC_PATH_NOT_FOUND;
210 }
211 if (numPaths > 0) {
212 for (size_t i = 0; i < numPaths; i++){
213 SAFE_FREE(pathArray[i]);
214 }
215 }
216 SAFE_FREE(pathArray);
217 return r;
218 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "tss2_fapi.h"
16 #include "ifapi_json_serialize.h"
17 #include "fapi_crypto.h"
18 #include "fapi_int.h"
19 #include "fapi_util.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 /** One-Call function for Fapi_NvExtend
26 *
27 * Performs an extend operation on an NV index with the type extend.
28 *
29 * @param[in,out] context the FAPI context
30 * @param[in] nvPath The path to the NV index that is extended
31 * @param[in] data The data to extend on the NV index
32 * @param[in] dataSize The size of the data to extend. Must be smaller than
33 * 1024
34 * @param[in] logData A JSON representation of the data that is written to the
35 * event log. May be NULL
36 *
37 * @retval TSS2_RC_SUCCESS: if the function call was a success.
38 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, nvPath, or data is NULL.
39 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
40 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
41 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV is not an extendable index.
42 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
43 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
44 * operation already pending.
45 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
46 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
47 * internal operations or return parameters.
48 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
49 * config file.
50 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
51 * the function.
52 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
53 * during authorization.
54 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
55 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
56 * this function needs to be called again.
57 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
58 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
59 * is not set.
60 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
61 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
62 */
63 TSS2_RC
64 Fapi_NvExtend(
65 FAPI_CONTEXT *context,
66 char const *nvPath,
67 uint8_t const *data,
68 size_t dataSize,
69 char const *logData)
70 {
71 LOG_TRACE("called for context:%p", context);
72
73 TSS2_RC r, r2;
74
75 /* Check for NULL parameters */
76 check_not_null(context);
77 check_not_null(nvPath);
78 check_not_null(data);
79
80 /* Check whether TCTI and ESYS are initialized */
81 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
82 TSS2_FAPI_RC_NO_TPM);
83
84 /* If the async state automata of FAPI shall be tested, then we must not set
85 the timeouts of ESYS to blocking mode.
86 During testing, the mssim tcti will ensure multiple re-invocations.
87 Usually however the synchronous invocations of FAPI shall instruct ESYS
88 to block until a result is available. */
89 #ifndef TEST_FAPI_ASYNC
90 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
91 return_if_error_reset_state(r, "Set Timeout to blocking");
92 #endif /* TEST_FAPI_ASYNC */
93
94 r = Fapi_NvExtend_Async(context, nvPath, data, dataSize, logData);
95 return_if_error_reset_state(r, "NV_Extend");
96
97 do {
98 /* We wait for file I/O to be ready if the FAPI state automata
99 are in a file I/O state. */
100 r = ifapi_io_poll(&context->io);
101 return_if_error(r, "Something went wrong with IO polling");
102
103 /* Repeatedly call the finish function, until FAPI has transitioned
104 through all execution stages / states of this invocation. */
105 r = Fapi_NvExtend_Finish(context);
106 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
107
108 /* Reset the ESYS timeout to non-blocking, immediate response. */
109 r2 = Esys_SetTimeout(context->esys, 0);
110 return_if_error(r2, "Set Timeout to non-blocking");
111
112 return_if_error_reset_state(r, "NV_Extend");
113
114 LOG_TRACE("finished");
115 return TSS2_RC_SUCCESS;
116 }
117
118 /** Asynchronous function for Fapi_NvExtend
119 *
120 * Performs an extend operation on an NV index with the type extend.
121 *
122 * Call Fapi_NvExtend_Finish to finish the execution of this command.
123 *
124 * @param[in,out] context the FAPI context
125 * @param[in] nvPath The path to the NV index that is extended
126 * @param[in] data The data to extend on the NV index
127 * @param[in] dataSize The size of the data to extend. Must be smaller than
128 * 1024
129 * @param[in] logData A JSON representation of the data that is written to the
130 * event log. May be NULL
131 *
132 * @retval TSS2_RC_SUCCESS: if the function call was a success.
133 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, nvPath, or data is NULL.
134 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
135 * @retval TSS2_FAPI_RC_BAD_VALUE: if dataSize is larger than 1024
136 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
137 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV is not an extendable index.
138 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
139 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
140 * operation already pending.
141 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
142 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
143 * internal operations or return parameters.
144 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
145 * config file.
146 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
147 * during authorization.
148 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
149 */
150 TSS2_RC
151 Fapi_NvExtend_Async(
152 FAPI_CONTEXT *context,
153 char const *nvPath,
154 uint8_t const *data,
155 size_t dataSize,
156 char const *logData)
157 {
158 LOG_TRACE("called for context:%p", context);
159 LOG_TRACE("nvPath: %s", nvPath);
160 if (data) {
161 LOGBLOB_TRACE(data, dataSize, "data");
162 } else {
163 LOG_TRACE("data: (null) dataSize: %zi", dataSize);
164 }
165 LOG_TRACE("logData: %s", logData);
166
167 TSS2_RC r;
168
169 /* Check for NULL parameters */
170 check_not_null(context);
171 check_not_null(nvPath);
172 check_not_null(data);
173
174 /* Check for maximum allowed dataSize. */
175 if (dataSize > 1024) {
176 LOG_ERROR("dataSize exceeds allowed maximum of 1024. dataSize = %zi", dataSize);
177 return TSS2_FAPI_RC_BAD_VALUE;
178 }
179
180 /* Helpful alias pointers */
181 IFAPI_NV_Cmds * command = &context->nv_cmd;
182
183 memset(command, 0 ,sizeof(IFAPI_NV_Cmds));
184
185 /* Copy parameters to context for use during _Finish. */
186 uint8_t *in_data = malloc(dataSize);
187 goto_if_null2(in_data, "Out of memory", r, TSS2_FAPI_RC_MEMORY,
188 error_cleanup);
189 memcpy(in_data, data, dataSize);
190 command->data = in_data;
191 strdup_check(command->nvPath, nvPath, r, error_cleanup);
192 strdup_check(command->logData, logData, r, error_cleanup);
193 command->numBytes = dataSize;
194
195 /* Reset all context-internal session state information. */
196 r = ifapi_session_init(context);
197 return_if_error(r, "Initialize NV_Extend");
198
199 /* Load the nv index metadata from the keystore. */
200 r = ifapi_keystore_load_async(&context->keystore, &context->io, command->nvPath);
201 goto_if_error2(r, "Could not open: %s", error_cleanup, command->nvPath);
202
203 /* Initialize the context state for this operation. */
204 context->state = NV_EXTEND_READ;
205 LOG_TRACE("finished");
206 return r;
207
208 error_cleanup:
209 /* Cleanup duplicated input parameters that were copied before. */
210 SAFE_FREE(command->data);
211 SAFE_FREE(command->nvPath);
212 SAFE_FREE(command->logData);
213 return r;
214 }
215
216 /** Asynchronous finish function for Fapi_NvExtend
217 *
218 * This function should be called after a previous Fapi_NvExtend.
219 *
220 * @param[in,out] context The FAPI_CONTEXT
221 *
222 * @retval TSS2_RC_SUCCESS: if the function call was a success.
223 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
224 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
225 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
226 * operation already pending.
227 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
228 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
229 * internal operations or return parameters.
230 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
231 * complete. Call this function again later.
232 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
233 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
234 * the function.
235 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
236 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
237 * during authorization.
238 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
239 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
240 * is not set.
241 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
242 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
243 * was not successful.
244 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
245 */
246 TSS2_RC
247 Fapi_NvExtend_Finish(
248 FAPI_CONTEXT *context)
249 {
250 LOG_TRACE("called for context:%p", context);
251
252 TSS2_RC r;
253 ESYS_TR authIndex;
254 json_object *jso = NULL;
255 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
256 TPMI_ALG_HASH hashAlg;
257 size_t hashSize;
258 ESYS_TR auth_session;
259
260 /* Check for NULL parameters */
261 check_not_null(context);
262
263 /* Helpful alias pointers */
264 IFAPI_NV_Cmds * command = &context->nv_cmd;
265 TPM2B_MAX_NV_BUFFER *auxData = (TPM2B_MAX_NV_BUFFER *)&context->aux_data;
266 ESYS_TR nvIndex = command->esys_handle;
267 const uint8_t *data = command->data;
268 IFAPI_OBJECT *object = &command->nv_object;
269 IFAPI_OBJECT *authObject = &command->auth_object;
270 IFAPI_EVENT *event = &command->pcr_event;
271
272 switch (context->state) {
273 statecase(context->state, NV_EXTEND_READ)
274 /* First check whether the file in object store can be updated. */
275 r = ifapi_keystore_check_writeable(&context->keystore, &context->io, command->nvPath);
276 goto_if_error_reset_state(r, "Check whether update object store is possible.", error_cleanup);
277
278 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
279 return_try_again(r);
280 return_if_error_reset_state(r, "read_finish failed");
281
282 if (object->objectType != IFAPI_NV_OBJ)
283 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is no NV object.", error_cleanup,
284 command->nvPath);
285
286 /* Initialize the NV index object for ESYS. */
287 r = ifapi_initialize_object(context->esys, object);
288 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
289
290 /* Store object info in context */
291 nvIndex = command->nv_object.handle;
292 command->esys_handle = context->nv_cmd.nv_object.handle;
293 command->nv_obj = object->misc.nv;
294
295 /* Determine the kind of authorization to be used. */
296 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_PPWRITE) {
297 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_PLATFORM);
298 authIndex = ESYS_TR_RH_PLATFORM;
299 } else {
300 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_OWNERWRITE) {
301 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_OWNER);
302 authIndex = ESYS_TR_RH_OWNER;
303 } else {
304 authIndex = nvIndex;
305 }
306 *authObject = *object;
307 }
308 command->auth_index = authIndex;
309 context->primary_state = PRIMARY_INIT;
310
311 /* Start a session for authorization. */
312 r = ifapi_get_sessions_async(context,
313 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
314 TPMA_SESSION_DECRYPT, 0);
315 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
316
317 fallthrough;
318
319 statecase(context->state, NV_EXTEND_WAIT_FOR_SESSION)
320 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
321 object->misc.nv.public.nvPublic.nameAlg);
322 return_try_again(r);
323 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
324
325 if (command->numBytes > TPM2_MAX_NV_BUFFER_SIZE) {
326 goto_error_reset_state(r, TSS2_FAPI_RC_BAD_VALUE,
327 "Buffer for NvExtend is too large.",
328 error_cleanup);
329 }
330
331 auxData->size = command->numBytes;
332 memcpy(&auxData->buffer[0], &data[0], auxData->size);
333 command->data_idx = auxData->size;
334 fallthrough;
335
336 statecase(context->state, NV_EXTEND_AUTHORIZE)
337 /* Prepare the authorization data for the NV index. */
338 r = ifapi_authorize_object(context, authObject, &auth_session);
339 return_try_again(r);
340 goto_if_error(r, "Authorize NV object.", error_cleanup);
341
342 /* Extend the data into the NV index. */
343 r = Esys_NV_Extend_Async(context->esys,
344 command->auth_index,
345 nvIndex,
346 auth_session,
347 ESYS_TR_NONE,
348 ESYS_TR_NONE,
349 auxData);
350 goto_if_error_reset_state(r, " Fapi_NvExtend_Async", error_cleanup);
351
352 command->bytesRequested = auxData->size;
353 command->data = (uint8_t *)data;
354
355 fallthrough;
356
357 statecase(context->state, NV_EXTEND_AUTH_SENT)
358 r = Esys_NV_Extend_Finish(context->esys);
359 return_try_again(r);
360
361 goto_if_error_reset_state(r, "FAPI NV_Extend_Finish", error_cleanup);
362
363 command->numBytes -= context->nv_cmd.bytesRequested;
364
365 /* Compute Digest of the current event */
366 hashAlg = object->misc.nv.public.nvPublic.nameAlg;
367 r = ifapi_crypto_hash_start(&cryptoContext, hashAlg);
368 return_if_error(r, "crypto hash start");
369
370 HASH_UPDATE_BUFFER(cryptoContext,
371 &auxData->buffer[0], auxData->size,
372 r, error_cleanup);
373
374 r = ifapi_crypto_hash_finish(&cryptoContext,
375 (uint8_t *)
376 &event->digests.digests[0].digest,
377 &hashSize);
378 return_if_error(r, "crypto hash finish");
379
380 event->digests.digests[0].hashAlg = hashAlg;
381 event->digests.count = 1;
382 event->pcr = object->misc.nv.public.nvPublic.nvIndex;
383 event->type = IFAPI_TSS_EVENT_TAG;
384 memcpy(&event->sub_event.tss_event.data.buffer[0],
385 &auxData->buffer[0], auxData->size);
386 event->sub_event.tss_event.data.size = auxData->size;
387 if (command->logData) {
388 strdup_check(event->sub_event.tss_event.event, command->logData,
389 r, error_cleanup);
390 } else {
391 event->sub_event.tss_event.event = NULL;
392 }
393
394 /* Event log of the NV object has to be extended */
395 if (command->nv_object.misc.nv.event_log) {
396 command->jso_event_log
397 = json_tokener_parse(command->nv_object.misc.nv.event_log);
398 goto_if_null2(command->jso_event_log, "Out of memory", r,
399 TSS2_FAPI_RC_MEMORY,
400 error_cleanup);
401 json_type jsoType = json_object_get_type(command->jso_event_log);
402 /* libjson-c does not deliver an array if array has only one element */
403 if (jsoType != json_type_array) {
404 json_object *jsonArray = json_object_new_array();
405 json_object_array_add(jsonArray, command->jso_event_log);
406 command->jso_event_log = jsonArray;
407 }
408 } else {
409 /* First event */
410 command->jso_event_log = json_object_new_array();
411 }
412 command->pcr_event.recnum =
413 json_object_array_length(command->jso_event_log) + 1;
414
415 r = ifapi_json_IFAPI_EVENT_serialize(&command->pcr_event, &jso);
416 goto_if_error(r, "Error serialize event", error_cleanup);
417
418 json_object_array_add(command->jso_event_log, jso);
419 SAFE_FREE(object->misc.nv.event_log);
420 strdup_check(object->misc.nv.event_log,
421 json_object_to_json_string_ext(command->jso_event_log,
422 JSON_C_TO_STRING_PRETTY),
423 r, error_cleanup);
424
425 /* Perform esys serialization if necessary */
426 r = ifapi_esys_serialize_object(context->esys, &command->nv_object);
427 goto_if_error(r, "Prepare serialization", error_cleanup);
428
429 /* Start writing the NV object to the key store */
430 r = ifapi_keystore_store_async(&context->keystore, &context->io,
431 command->nvPath,
432 &command->nv_object);
433
434 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
435 command->nvPath);
436
437 fallthrough;
438
439 statecase(context->state, NV_EXTEND_WRITE)
440 /* Finish writing the NV object to the key store */
441 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
442 return_try_again(r);
443 return_if_error_reset_state(r, "write_finish failed");
444 fallthrough;
445
446 statecase(context->state, NV_EXTEND_CLEANUP)
447 /* Cleanup the session. */
448 r = ifapi_cleanup_session(context);
449 try_again_or_error_goto(r, "Cleanup", error_cleanup);
450
451 context->state = _FAPI_STATE_INIT;
452 r = TSS2_RC_SUCCESS;
453
454 break;
455
456 statecasedefault(context->state);
457 }
458
459 error_cleanup:
460 /* Cleanup any intermediate results and state stored in the context. */
461 if (command->jso_event_log)
462 json_object_put(command->jso_event_log);
463 ifapi_cleanup_ifapi_object(object);
464 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
465 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
466 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
467 if (cryptoContext) {
468 ifapi_crypto_hash_abort(&cryptoContext);
469 }
470 if (event)
471 ifapi_cleanup_event(event);
472 SAFE_FREE(command->data);
473 SAFE_FREE(command->nvPath);
474 SAFE_FREE(command->logData);
475 SAFE_FREE(object->misc.nv.event_log);
476 ifapi_session_clean(context);
477 LOG_TRACE("finished");
478 return r;
479 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "tss2_fapi.h"
16 #include "fapi_int.h"
17 #include "fapi_util.h"
18 #include "tss2_esys.h"
19 #define LOGMODULE fapi
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 /** One-Call function for Fapi_NvIncrement
24 *
25 * Increments an NV index that is a counter by 1.
26 *
27 * @param[in,out] context The FAPI_CONTEXT
28 * @param[in] nvPath The path to the NV index that is incremented.
29 *
30 * @retval TSS2_RC_SUCCESS: if the function call was a success.
31 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or nvPath is NULL.
32 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
33 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
34 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV index type is not
35 * TPM2_NT_COUNTER.
36 * @retval TSS2_FAPI_RC_NV_NOT_WRITEABLE: if the NV index is not writeable.
37 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
38 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
39 * operation already pending.
40 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
41 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
42 * internal operations or return parameters.
43 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
44 * config file.
45 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
46 * during authorization.
47 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
48 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
49 * the function.
50 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
51 * this function needs to be called again.
52 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
53 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
54 * is not set.
55 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
56 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
57 */
58 TSS2_RC
59 Fapi_NvIncrement(
60 FAPI_CONTEXT *context,
61 char const *nvPath)
62 {
63 LOG_TRACE("called for context:%p", context);
64
65 TSS2_RC r, r2;
66
67 /* Check for NULL parameters */
68 check_not_null(context);
69 check_not_null(nvPath);
70
71 /* Check whether TCTI and ESYS are initialized */
72 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
73 TSS2_FAPI_RC_NO_TPM);
74
75 /* If the async state automata of FAPI shall be tested, then we must not set
76 the timeouts of ESYS to blocking mode.
77 During testing, the mssim tcti will ensure multiple re-invocations.
78 Usually however the synchronous invocations of FAPI shall instruct ESYS
79 to block until a result is available. */
80 #ifndef TEST_FAPI_ASYNC
81 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
82 return_if_error_reset_state(r, "Set Timeout to blocking");
83 #endif /* TEST_FAPI_ASYNC */
84
85 r = Fapi_NvIncrement_Async(context, nvPath);
86 return_if_error_reset_state(r, "NV_Increment");
87
88 do {
89 /* We wait for file I/O to be ready if the FAPI state automata
90 are in a file I/O state. */
91 r = ifapi_io_poll(&context->io);
92 return_if_error(r, "Something went wrong with IO polling");
93
94 /* Repeatedly call the finish function, until FAPI has transitioned
95 through all execution stages / states of this invocation. */
96 r = Fapi_NvIncrement_Finish(context);
97 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
98
99 /* Reset the ESYS timeout to non-blocking, immediate response. */
100 r2 = Esys_SetTimeout(context->esys, 0);
101 return_if_error(r2, "Set Timeout to non-blocking");
102
103 return_if_error_reset_state(r, "NV_Increment");
104
105 LOG_TRACE("finished");
106 return TSS2_RC_SUCCESS;
107 }
108
109 /** Asynchronous function for Fapi_NvIncrement
110 *
111 * Increments an NV index that is a counter by 1.
112 *
113 * Call Fapi_NvIncrement_Finish to finish the execution of this command.
114 *
115 * @param[in,out] context The FAPI_CONTEXT
116 * @param[in] nvPath The path to the NV index that is incremented.
117 *
118 * @retval TSS2_RC_SUCCESS: if the function call was a success.
119 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or nvPath is NULL.
120 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
121 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
122 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV index type is not
123 * TPM2_NT_COUNTER.
124 * @retval TSS2_FAPI_RC_NV_NOT_WRITEABLE: if the NV index is not writeable.
125 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
126 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
127 * operation already pending.
128 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
129 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
130 * internal operations or return parameters.
131 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
132 * config file.
133 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
134 * during authorization.
135 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
136 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
137 * the function.
138 */
139 TSS2_RC
140 Fapi_NvIncrement_Async(
141 FAPI_CONTEXT *context,
142 char const *nvPath)
143 {
144 LOG_TRACE("called for context:%p", context);
145 LOG_TRACE("nvPath: %s", nvPath);
146
147 TSS2_RC r;
148
149 /* Check for NULL parameters */
150 check_not_null(context);
151 check_not_null(nvPath);
152
153 /* Helpful alias pointers */
154 IFAPI_NV_Cmds * command = &context->nv_cmd;
155
156 /* Reset all context-internal session state information. */
157 r = ifapi_session_init(context);
158 return_if_error(r, "Initialize NV_Increment");
159
160 /* Copy parameters to context for use during _Finish. */
161 memset(&context->nv_cmd, 0, sizeof(IFAPI_NV_Cmds));
162 strdup_check(command->nvPath, nvPath, r, error_cleanup);
163
164 command->rdata = NULL;
165
166 /* Load the NV index metadata from keystore. */
167 r = ifapi_keystore_load_async(&context->keystore, &context->io, command->nvPath);
168 goto_if_error2(r, "Could not open: %s", error_cleanup, command->nvPath);
169
170 /* Initialize the context state for this operation. */
171 context->state = NV_INCREMENT_READ;
172 LOG_TRACE("finished");
173 return TSS2_RC_SUCCESS;
174
175 error_cleanup:
176 /* Cleanup duplicated input parameters that were copied before. */
177 SAFE_FREE(command->nvPath);
178 return r;
179 }
180
181 /** Asynchronous finish function for Fapi_NvIncrement
182 *
183 * This function should be called after a previous Fapi_NvIncrement_Async.
184 *
185 * @param[in,out] context The FAPI_CONTEXT
186 *
187 * @retval TSS2_RC_SUCCESS: if the function call was a success.
188 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
189 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
190 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
191 * operation already pending.
192 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
193 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
194 * internal operations or return parameters.
195 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
196 * complete. Call this function again later.
197 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
198 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
199 * the function.
200 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
201 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
202 * during authorization.
203 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
204 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
205 * is not set.
206 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
207 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
208 * was not successful.
209 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
210 */
211 TSS2_RC
212 Fapi_NvIncrement_Finish(
213 FAPI_CONTEXT *context)
214 {
215 LOG_TRACE("called for context:%p", context);
216
217 TSS2_RC r;
218 json_object *jso = NULL;
219 ESYS_TR authIndex;
220 ESYS_TR auth_session;
221
222 /* Check for NULL parameters */
223 check_not_null(context);
224
225 /* Helpful alias pointers */
226 IFAPI_NV_Cmds * command = &context->nv_cmd;
227 IFAPI_OBJECT *object = &command->nv_object;
228 ESYS_TR nvIndex = command->esys_handle;
229 IFAPI_OBJECT *authObject = &command->auth_object;
230
231 switch (context->state) {
232 statecase(context->state, NV_INCREMENT_READ)
233 /* First check whether the file in object store can be updated. */
234 r = ifapi_keystore_check_writeable(&context->keystore, &context->io, command->nvPath);
235 goto_if_error_reset_state(r, "Check whether update object store is possible.", error_cleanup);
236
237 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
238 return_try_again(r);
239 return_if_error_reset_state(r, "read_finish failed");
240
241 if (object->objectType != IFAPI_NV_OBJ)
242 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is no NV object.", error_cleanup,
243 command->nvPath);
244
245 /* Initialize the NV index object for use with ESYS. */
246 r = ifapi_initialize_object(context->esys, object);
247 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
248
249 nvIndex = command->nv_object.handle;
250 command->esys_handle = context->nv_cmd.nv_object.handle;
251 command->nv_obj = object->misc.nv;
252
253 /* Determine auth object */
254 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_PPREAD) {
255 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_PLATFORM);
256 authIndex = ESYS_TR_RH_PLATFORM;
257 } else {
258 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_OWNERREAD) {
259 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_OWNER);
260 authIndex = ESYS_TR_RH_OWNER;
261 } else {
262 authIndex = nvIndex;
263 }
264 *authObject = *object;
265 }
266 command->auth_index = authIndex;
267 context->primary_state = PRIMARY_INIT;
268
269 /* Prepare the session for authorization */
270 r = ifapi_get_sessions_async(context,
271 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
272 0, 0);
273 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
274
275 fallthrough;
276
277 statecase(context->state, NV_INCREMENT_WAIT_FOR_SESSION)
278 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
279 object->misc.nv.public.nvPublic.nameAlg);
280 return_try_again(r);
281 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
282
283 fallthrough;
284
285 statecase(context->state, NV_INCREMENT_AUTHORIZE)
286 /* Authorize the session for accessing the NV-index. */
287 r = ifapi_authorize_object(context, authObject, &auth_session);
288 return_try_again(r);
289 goto_if_error(r, "Authorize NV object.", error_cleanup);
290
291 /* Prepare increment */
292 r = Esys_NV_Increment_Async(context->esys, command->auth_index,
293 nvIndex,
294 auth_session,
295 ESYS_TR_NONE, ESYS_TR_NONE);
296 goto_if_error_reset_state(r, " Fapi_NvIncrement_Async", error_cleanup);
297
298 fallthrough;
299
300 statecase(context->state, NV_INCREMENT_AUTH_SENT)
301 r = Esys_NV_Increment_Finish(context->esys);
302 return_try_again(r);
303 goto_if_error_reset_state(r, "FAPI NV_Increment_Finish", error_cleanup);
304
305 /* Perform esys serialization if necessary */
306 r = ifapi_esys_serialize_object(context->esys, &command->nv_object);
307 goto_if_error(r, "Prepare serialization", error_cleanup);
308
309 /* Start writing the NV object to the key store */
310 r = ifapi_keystore_store_async(&context->keystore, &context->io,
311 command->nvPath,
312 &command->nv_object);
313 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
314 command->nvPath);
315
316 fallthrough;
317
318 statecase(context->state, NV_INCREMENT_WRITE)
319 /* Finish writing the NV object to the key store */
320 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
321 return_try_again(r);
322 return_if_error_reset_state(r, "write_finish failed");
323 fallthrough;
324
325 statecase(context->state, NV_INCREMENT_CLEANUP)
326 /* Cleanup the authorization session. */
327 r = ifapi_cleanup_session(context);
328 try_again_or_error_goto(r, "Cleanup", error_cleanup);
329
330 context->state = _FAPI_STATE_INIT;
331 break;
332
333 statecasedefault(context->state);
334 }
335
336 error_cleanup:
337 /* Cleanup any intermediate results and state stored in the context. */
338 ifapi_cleanup_ifapi_object(&command->nv_object);
339 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
340 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
341 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
342 SAFE_FREE(command->nvPath);
343 SAFE_FREE(jso);
344 ifapi_session_clean(context);
345 LOG_TRACE("finished");
346 return r;
347 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "tss2_fapi.h"
16 #include "fapi_int.h"
17 #include "fapi_util.h"
18 #include "tss2_esys.h"
19 #define LOGMODULE fapi
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 /** One-Call function for Fapi_NvRead
24 *
25 * Reads data from an NV index within the TPM.
26 * The FAPI will automatically do the multiple reads if the NV index is larger
27 * than the TPM's TPM2_MAX_NV_BUFFER_SIZE.
28 *
29 * @param[in,out] context The FAPI_CONTEXT
30 * @param[in] nvPath The path of the NV index to read
31 * @param[out] data The data that was read from the NV index
32 * @param[out] size The size of data in bytes. May be NULL
33 * @param[out] logData The log data of the NV index if the index is of type
34 * "extend". May be NULL
35 *
36 * @retval TSS2_RC_SUCCESS: if the function call was a success.
37 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, nvPath or data is NULL.
38 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
39 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
40 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED: if authorization fails.
41 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN: if don’t know how to authenticate.
42 * @retval TSS2_FAPI_RC_NV_NOT_READABLE: if the NV is not a readable index.
43 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
44 * operation already pending.
45 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
46 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
47 * internal operations or return parameters.
48 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
49 * config file.
50 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
51 * during authorization.
52 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
53 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
54 * the function.
55 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
56 * this function needs to be called again.
57 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
58 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
59 * was not successful.
60 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
61 */
62 TSS2_RC
63 Fapi_NvRead(
64 FAPI_CONTEXT *context,
65 char const *nvPath,
66 uint8_t **data,
67 size_t *size,
68 char **logData)
69 {
70 LOG_TRACE("called for context:%p", context);
71
72 TSS2_RC r, r2;
73
74 /* Check for NULL parameters */
75 check_not_null(context);
76 check_not_null(nvPath);
77 check_not_null(data);
78
79 /* Check whether TCTI and ESYS are initialized */
80 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
81 TSS2_FAPI_RC_NO_TPM);
82
83 /* If the async state automata of FAPI shall be tested, then we must not set
84 the timeouts of ESYS to blocking mode.
85 During testing, the mssim tcti will ensure multiple re-invocations.
86 Usually however the synchronous invocations of FAPI shall instruct ESYS
87 to block until a result is available. */
88 #ifndef TEST_FAPI_ASYNC
89 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
90 return_if_error_reset_state(r, "Set Timeout to blocking");
91 #endif /* TEST_FAPI_ASYNC */
92
93 r = Fapi_NvRead_Async(context, nvPath);
94 return_if_error_reset_state(r, "NV_Read");
95
96 do {
97 /* We wait for file I/O to be ready if the FAPI state automata
98 are in a file I/O state. */
99 r = ifapi_io_poll(&context->io);
100 return_if_error(r, "Something went wrong with IO polling");
101
102 /* Repeatedly call the finish function, until FAPI has transitioned
103 through all execution stages / states of this invocation. */
104 r = Fapi_NvRead_Finish(context, data, size, logData);
105 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
106
107 /* Reset the ESYS timeout to non-blocking, immediate response. */
108 r2 = Esys_SetTimeout(context->esys, 0);
109 return_if_error(r2, "Set Timeout to non-blocking");
110
111 return_if_error_reset_state(r, "NV_Read");
112
113 LOG_TRACE("finished");
114 return TSS2_RC_SUCCESS;
115 }
116
117 /** Asynchronous function for Fapi_NvRead
118 *
119 * Reads data from an NV index within the TPM.
120 * The FAPI will automatically do the multiple reads if the NV index is larger
121 * than the TPM's TPM2_MAX_NV_BUFFER_SIZE.
122 *
123 * Call Fapi_NvRead_Finish to finish the execution of this command.
124 *
125 * @param[in,out] context The FAPI_CONTEXT
126 * @param[in] nvPath The path of the NV index to read
127 *
128 * @retval TSS2_RC_SUCCESS: if the function call was a success.
129 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or nvPath is NULL. *
130 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
131 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
132 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED: if authorization fails.
133 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN: if don’t know how to authenticate.
134 * @retval TSS2_FAPI_RC_NV_NOT_READABLE: if the NV is not a readable index.
135 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
136 * operation already pending.
137 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
138 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
139 * internal operations or return parameters.
140 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
141 * config file.
142 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
143 * during authorization.
144 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
145 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
146 * the function.
147 */
148 TSS2_RC
149 Fapi_NvRead_Async(
150 FAPI_CONTEXT *context,
151 char const *nvPath)
152 {
153 LOG_TRACE("called for context:%p", context);
154 LOG_TRACE("nvPath: %s", nvPath);
155
156 TSS2_RC r;
157
158 /* Check for NULL parameters */
159 check_not_null(context);
160 check_not_null(nvPath);
161
162 /* Helpful alias pointers */
163 IFAPI_NV_Cmds * command = &context->nv_cmd;
164
165 /* Reset all context-internal session state information. */
166 r = ifapi_session_init(context);
167 return_if_error(r, "Initialize NvRead");
168
169 memset(command, 0, sizeof(IFAPI_NV_Cmds));
170
171 /* Copy parameters to context for use during _Finish. */
172 strdup_check(command->nvPath, nvPath, r, error_cleanup);
173
174 /* Load the NV index metadata from keystore. */
175 r = ifapi_keystore_load_async(&context->keystore, &context->io, command->nvPath);
176 goto_if_error_reset_state(r, "Could not open: %s", error_cleanup, command->nvPath);
177
178 /* Initialize the context state for this operation. */
179 context->state = NV_READ_READ;
180 LOG_TRACE("finished");
181 return TSS2_RC_SUCCESS;
182
183 error_cleanup:
184 /* Cleanup duplicated input parameters that were copied before. */
185 SAFE_FREE(command->nvPath);
186 return r;
187 }
188
189 /** Asynchronous finish function for Fapi_NvRead
190 *
191 * This function should be called after a previous Fapi_NvRead_Async.
192 *
193 * @param[in,out] context The FAPI_CONTEXT
194 * @param[out] data The data that was read from the NV index
195 * @param[out] size The size of data in bytes. May be NULL
196 * @param[out] logData The log data of the NV index if the index is of type
197 * "extend". May be NULL
198 *
199 * @retval TSS2_RC_SUCCESS: if the function call was a success.
200 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or data is NULL.
201 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
202 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
203 * operation already pending.
204 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
205 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
206 * internal operations or return parameters.
207 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
208 * complete. Call this function again later.
209 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
210 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
211 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
212 * the function.
213 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
214 * during authorization.
215 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
216 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
217 * is not set.
218 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
219 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
220 * was not successful.
221 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
222 */
223 TSS2_RC
224 Fapi_NvRead_Finish(
225 FAPI_CONTEXT *context,
226 uint8_t **data,
227 size_t *size,
228 char **logData)
229 {
230 LOG_TRACE("called for context:%p", context);
231
232 TSS2_RC r;
233 ESYS_TR authIndex;
234 size_t readSize;
235
236 /* Check for NULL parameters */
237 check_not_null(context);
238 check_not_null(data);
239
240 /* Helpful alias pointers */
241 IFAPI_NV_Cmds *command = &context->nv_cmd;
242 IFAPI_OBJECT *object = &command->nv_object;
243 IFAPI_OBJECT *authObject = &command->auth_object;
244
245 switch (context->state) {
246 statecase(context->state, NV_READ_READ)
247 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
248 return_try_again(r);
249 return_if_error_reset_state(r, "read_finish failed");
250
251 if (object->objectType != IFAPI_NV_OBJ)
252 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is no NV object.", error_cleanup,
253 command->nvPath);
254
255 /* Initialize the NV index object for use with ESYS. */
256 r = ifapi_initialize_object(context->esys, object);
257 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
258
259 command->esys_handle = object->handle;
260 command->nv_obj = object->misc.nv;
261
262 if (size)
263 *size = object->misc.nv.public.nvPublic.dataSize;
264 command->numBytes = object->misc.nv.public.nvPublic.dataSize;
265
266 /* Determine auth object */
267 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_PPREAD) {
268 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_PLATFORM);
269 authIndex = ESYS_TR_RH_PLATFORM;
270 } else {
271 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_OWNERREAD) {
272 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_OWNER);
273 authIndex = ESYS_TR_RH_OWNER;
274 } else {
275 authIndex = object->handle;
276 }
277 *authObject = *object;
278 }
279 command->auth_index = authIndex;
280 context->primary_state = PRIMARY_INIT;
281
282 /* Prepare session for authorization and data encryption. */
283 r = ifapi_get_sessions_async(context,
284 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
285 TPMA_SESSION_ENCRYPT, 0);
286 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
287
288 fallthrough;
289
290 statecase(context->state, NV_READ_WAIT_FOR_SESSION)
291 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
292 object->misc.nv.public.nvPublic.nameAlg);
293 return_try_again(r);
294 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
295
296 command->nv_read_state = NV_READ_INIT;
297
298 fallthrough;
299
300 statecase(context->state, NV_READ_WAIT)
301 if (data) {
302 /* Read the data from the TPM. */
303 r = ifapi_nv_read(context, data, &readSize);
304 return_try_again(r);
305
306 goto_if_error_reset_state(r, " FAPI NV_Read", error_cleanup);
307 }
308
309 if (logData) {
310 /* Duplicate the logdata that may have been stored during a
311 NvExtend command. */
312 strdup_check(*logData, object->misc.nv.event_log, r, error_cleanup);
313 }
314 fallthrough;
315
316 statecase(context->state, NV_READ_CLEANUP)
317 /* Cleanup the session used for authorization. */
318 r = ifapi_cleanup_session(context);
319 try_again_or_error_goto(r, "Cleanup", error_cleanup);
320
321 context->state = _FAPI_STATE_INIT;
322 break;
323
324 statecasedefault(context->state);
325 }
326
327 error_cleanup:
328 /* Cleanup any intermediate results and state stored in the context. */
329 ifapi_cleanup_ifapi_object(&command->nv_object);
330 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
331 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
332 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
333 SAFE_FREE(command->nvPath);
334 //SAFE_FREE(context->nv_cmd.tes);
335 ifapi_session_clean(context);
336 LOG_TRACE("finished");
337 return r;
338 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "tss2_fapi.h"
16 #include "fapi_int.h"
17 #include "fapi_util.h"
18 #include "tss2_esys.h"
19 #define LOGMODULE fapi
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 /** One-Call function for Fapi_NvSetBits
24 *
25 * Sets bits in an NV index that was created as a bit field. Any number of bits
26 * from 0 to 64 may be SET.
27 *
28 * @param[in,out] context The FAPI_CONTEXT
29 * @param[in] nvPath The path to the NV index where bits are set
30 * @param[in] bitmap The map of the bits to set
31 *
32 * @retval TSS2_RC_SUCCESS: if the function call was a success.
33 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or nvPath is NULL.
34 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
35 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
36 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV index type is not
37 * TPM2_NT_COUNTER.
38 * @retval TSS2_FAPI_RC_NV_NOT_WRITEABLE: if the NV is not a writeable index.
39 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
40 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
41 * operation already pending.
42 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
43 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
44 * internal operations or return parameters.
45 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
46 * config file.
47 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
48 * during authorization.
49 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
50 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
51 * the function.
52 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
53 * this function needs to be called again.
54 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
55 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
56 * is not set.
57 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
58 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
59 */
60 TSS2_RC
61 Fapi_NvSetBits(
62 FAPI_CONTEXT *context,
63 char const *nvPath,
64 uint64_t bitmap)
65 {
66 LOG_TRACE("called for context:%p", context);
67
68 TSS2_RC r, r2;
69
70 /* Check for NULL parameters */
71 check_not_null(context);
72 check_not_null(nvPath);
73
74 /* Check whether TCTI and ESYS are initialized */
75 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
76 TSS2_FAPI_RC_NO_TPM);
77
78 /* If the async state automata of FAPI shall be tested, then we must not set
79 the timeouts of ESYS to blocking mode.
80 During testing, the mssim tcti will ensure multiple re-invocations.
81 Usually however the synchronous invocations of FAPI shall instruct ESYS
82 to block until a result is available. */
83 #ifndef TEST_FAPI_ASYNC
84 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
85 return_if_error_reset_state(r, "Set Timeout to blocking");
86 #endif /* TEST_FAPI_ASYNC */
87
88 r = Fapi_NvSetBits_Async(context, nvPath, bitmap);
89 return_if_error_reset_state(r, "NV_SetBits");
90
91 do {
92 /* We wait for file I/O to be ready if the FAPI state automata
93 are in a file I/O state. */
94 r = ifapi_io_poll(&context->io);
95 return_if_error(r, "Something went wrong with IO polling");
96
97 /* Repeatedly call the finish function, until FAPI has transitioned
98 through all execution stages / states of this invocation. */
99 r = Fapi_NvSetBits_Finish(context);
100 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
101
102 /* Reset the ESYS timeout to non-blocking, immediate response. */
103 r2 = Esys_SetTimeout(context->esys, 0);
104 return_if_error(r2, "Set Timeout to non-blocking");
105
106 return_if_error_reset_state(r, "NV_SetBits");
107
108 LOG_TRACE("finished");
109 return TSS2_RC_SUCCESS;
110 }
111
112 /** Asynchronous function for Fapi_NvSetBits
113 *
114 * Sets bits in an NV index that was created as a bit field. Any number of bits
115 * from 0 to 64 may be SET.
116 *
117 * Call Fapi_NvSetBits_Finish to finish the execution of this command.
118 *
119 * @param[in,out] context The FAPI_CONTEXT
120 * @param[in] nvPath The path to the NV index where bits are set
121 * @param[in] bitmap The map of the bits to set
122 *
123 * @retval TSS2_RC_SUCCESS: if the function call was a success.
124 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or nvPath is NULL.
125 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
126 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
127 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV index type is not
128 * TPM2_NT_COUNTER.
129 * @retval TSS2_FAPI_RC_NV_NOT_WRITEABLE: if the NV is not a writeable index.
130 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
131 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
132 * operation already pending.
133 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
134 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
135 * internal operations or return parameters.
136 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
137 * config file.
138 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
139 * during authorization.
140 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
141 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
142 * the function.
143 */
144 TSS2_RC
145 Fapi_NvSetBits_Async(
146 FAPI_CONTEXT *context,
147 char const *nvPath,
148 uint64_t bitmap)
149 {
150 LOG_TRACE("called for context:%p", context);
151 LOG_TRACE("nvPath: %s", nvPath);
152 LOG_TRACE("bitmap: 0x%" PRIx64, bitmap);
153
154 TSS2_RC r;
155
156 /* Check for NULL parameters */
157 check_not_null(context);
158 check_not_null(nvPath);
159
160 /* Helpful alias pointers */
161 IFAPI_NV_Cmds * command = &context->nv_cmd;
162
163 /* Reset all context-internal session state information. */
164 r = ifapi_session_init(context);
165 return_if_error(r, "Initialize NV_SetBits");
166
167 /* Store the parameter in the FAPI context */
168 memset(&context->nv_cmd, 0, sizeof(IFAPI_NV_Cmds));
169 memset(&command->nv_object, 0, sizeof(IFAPI_OBJECT));
170 strdup_check(command->nvPath, nvPath, r, error_cleanup);
171 command->bitmap = bitmap;
172 command->rdata = NULL;
173
174 /* Load the NV index metadata from keystore. */
175 r = ifapi_keystore_load_async(&context->keystore, &context->io, command->nvPath);
176 goto_if_error2(r, "Could not open: %s", error_cleanup, command->nvPath);
177
178 /* Initialize the context state for this operation. */
179 context->state = NV_SET_BITS_READ;
180 LOG_TRACE("finished");
181 return TSS2_RC_SUCCESS;
182
183 error_cleanup:
184 /* Cleanup duplicated input parameters that were copied before. */
185 SAFE_FREE(command->nvPath);
186 return r;
187 }
188
189 /** Asynchronous finish function for Fapi_NnSetBits
190 *
191 * This function should be called after a previous Fapi_NvSetBIts_Async.
192 *
193 * @param[in,out] context The FAPI_CONTEXT
194 *
195 * @retval TSS2_RC_SUCCESS: if the function call was a success.
196 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
197 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
198 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
199 * operation already pending.
200 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
201 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
202 * internal operations or return parameters.
203 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
204 * complete. Call this function again later.
205 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
206 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
207 * the function.
208 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
209 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
210 * during authorization.
211 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
212 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
213 * is not set.
214 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
215 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
216 * was not successful.
217 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
218 */
219 TSS2_RC
220 Fapi_NvSetBits_Finish(
221 FAPI_CONTEXT *context)
222 {
223 LOG_TRACE("called for context:%p", context);
224
225 TSS2_RC r;
226 json_object *jso = NULL;
227 ESYS_TR authIndex;
228 ESYS_TR auth_session;
229
230 /* Check for NULL parameters */
231 check_not_null(context);
232
233 /* Helpful alias pointers */
234 IFAPI_NV_Cmds * command = &context->nv_cmd;
235 IFAPI_OBJECT *object = &command->nv_object;
236 ESYS_TR nvIndex = command->esys_handle;
237 IFAPI_OBJECT *authObject = &command->auth_object;
238
239 switch (context->state) {
240 statecase(context->state, NV_SET_BITS_READ)
241 /* First check whether the file in object store can be updated. */
242 r = ifapi_keystore_check_writeable(&context->keystore, &context->io, command->nvPath);
243 goto_if_error_reset_state(r, "Check whether update object store is possible.", error_cleanup);
244
245 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
246 return_try_again(r);
247 return_if_error_reset_state(r, "read_finish failed");
248
249 if (object->objectType != IFAPI_NV_OBJ)
250 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is no NV object.", error_cleanup,
251 command->nvPath);
252
253 /* Initialize the NV index object for use with ESYS. */
254 r = ifapi_initialize_object(context->esys, object);
255 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
256
257 nvIndex = command->nv_object.handle;
258 command->esys_handle = object->handle;
259 command->nv_obj = object->misc.nv;
260
261 /* Determine auth object */
262 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_PPREAD) {
263 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_PLATFORM);
264 authIndex = ESYS_TR_RH_PLATFORM;
265 } else {
266 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_OWNERREAD) {
267 ifapi_init_hierarchy_object(authObject, ESYS_TR_RH_OWNER);
268 authIndex = ESYS_TR_RH_OWNER;
269 } else {
270 authIndex = nvIndex;
271 }
272 *authObject = *object;
273 }
274 command->auth_index = authIndex;
275 context->primary_state = PRIMARY_INIT;
276
277 /* Prepare session for authorization */
278 r = ifapi_get_sessions_async(context,
279 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
280 0, 0);
281 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
282
283 fallthrough;
284
285 statecase(context->state, NV_SET_BITS_WAIT_FOR_SESSION)
286 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
287 object->misc.nv.public.nvPublic.nameAlg);
288 return_try_again(r);
289
290 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
291
292 fallthrough;
293
294 statecase(context->state, NV_SET_BITS_AUTHORIZE)
295 /* Authorize the session to be used for accessing the NV index. */
296 r = ifapi_authorize_object(context, authObject, &auth_session);
297 return_try_again(r);
298 goto_if_error(r, "Authorize NV object.", error_cleanup);
299
300 /* Call the SetBit TPM operation. */
301 r = Esys_NV_SetBits_Async(context->esys, command->auth_index, nvIndex,
302 auth_session,
303 ESYS_TR_NONE, ESYS_TR_NONE,
304 command->bitmap);
305
306 goto_if_error_reset_state(r, " Fapi_NvSetBits_Async", error_cleanup);
307
308 fallthrough;
309
310 statecase(context->state, NV_SET_BITS_AUTH_SENT)
311 r = Esys_NV_SetBits_Finish(context->esys);
312 return_try_again(r);
313 goto_if_error_reset_state(r, "FAPI NV_SetBits_Finish", error_cleanup);
314
315 /* Serialize the ESYS object for updating the metadata in the keystore. */
316 r = ifapi_esys_serialize_object(context->esys, object);
317 goto_if_error(r, "Prepare serialization", error_cleanup);
318
319 /* Start writing the NV object to the key store */
320 r = ifapi_keystore_store_async(&context->keystore, &context->io,
321 command->nvPath,
322 object);
323 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
324 command->nvPath);
325 fallthrough;
326
327 statecase(context->state, NV_SET_BITS_WRITE)
328 /* Finish writing the NV object to the key store */
329 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
330 return_try_again(r);
331 return_if_error_reset_state(r, "write_finish failed");
332
333 fallthrough;
334
335 statecase(context->state, NV_SET_BITS_CLEANUP)
336 /* Cleanup the session used for authorization. */
337 r = ifapi_cleanup_session(context);
338 try_again_or_error_goto(r, "Cleanup", error_cleanup);
339
340 context->state = _FAPI_STATE_INIT;
341 LOG_DEBUG("success");
342
343 break;
344
345 statecasedefault(context->state);
346 }
347
348 error_cleanup:
349 /* Cleanup any intermediate results and state stored in the context. */
350 SAFE_FREE(command->nvPath);
351 SAFE_FREE(jso);
352 ifapi_session_clean(context);
353 ifapi_cleanup_ifapi_object(object);
354 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
355 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
356 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
357 LOG_TRACE("finished");
358 return r;
359 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <errno.h>
14
15 #include "tss2_fapi.h"
16 #include "fapi_int.h"
17 #include "fapi_util.h"
18 #include "tss2_esys.h"
19 #include "fapi_policy.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 /** One-Call function for Fapi_NvWrite
25 *
26 * Writes data to a "regular" (not pin, extend or counter) NV index.
27 *
28 * @param[in,out] context The FAPI_CONTEXT
29 * @param[in] nvPath The path of the NV index to write
30 * @param[in] data The data to write to the NV index
31 * @param[in] size The size of data in bytes
32 *
33 * @retval TSS2_RC_SUCCESS: if the function call was a success.
34 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, nvPath, or data is NULL.
35 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
36 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
37 * @retval TSS2_FAPI_RC_NV_EXCEEDED: if the NV is not large enough for the data
38 * to be written.
39 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV index is not a "regular" one.
40 * @retval TSS2_FAPI_RC_NV_NOT_WRITEABLE: if the NV is not a writeable index.
41 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
42 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
43 * operation already pending.
44 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
45 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
46 * internal operations or return parameters.
47 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
48 * config file.
49 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
50 * this function needs to be called again.
51 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
52 * the function.
53 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
54 * during authorization.
55 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
56 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
57 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
58 * is not set.
59 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
60 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
61 */
62 TSS2_RC
63 Fapi_NvWrite(
64 FAPI_CONTEXT *context,
65 char const *nvPath,
66 uint8_t const *data,
67 size_t size)
68 {
69 LOG_TRACE("called for context:%p", context);
70
71 TSS2_RC r, r2;
72
73 /* Check for NULL parameters */
74 check_not_null(context);
75 check_not_null(nvPath);
76 check_not_null(data);
77
78 /* Check whether TCTI and ESYS are initialized */
79 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
80 TSS2_FAPI_RC_NO_TPM);
81
82 /* If the async state automata of FAPI shall be tested, then we must not set
83 the timeouts of ESYS to blocking mode.
84 During testing, the mssim tcti will ensure multiple re-invocations.
85 Usually however the synchronous invocations of FAPI shall instruct ESYS
86 to block until a result is available. */
87 #ifndef TEST_FAPI_ASYNC
88 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
89 return_if_error_reset_state(r, "Set Timeout to blocking");
90 #endif /* TEST_FAPI_ASYNC */
91
92 r = Fapi_NvWrite_Async(context, nvPath, data, size);
93 return_if_error_reset_state(r, "NV_Write");
94
95 do {
96 /* We wait for file I/O to be ready if the FAPI state automata
97 are in a file I/O state. */
98 r = ifapi_io_poll(&context->io);
99 return_if_error(r, "Something went wrong with IO polling");
100
101 /* Repeatedly call the finish function, until FAPI has transitioned
102 through all execution stages / states of this invocation. */
103 r = Fapi_NvWrite_Finish(context);
104 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
105
106 /* Reset the ESYS timeout to non-blocking, immediate response. */
107 r2 = Esys_SetTimeout(context->esys, 0);
108 return_if_error(r2, "Set Timeout to non-blocking");
109
110 return_if_error_reset_state(r, "NV_Write");
111
112 LOG_TRACE("finished");
113 return TSS2_RC_SUCCESS;
114 }
115
116 /** Asynchronous function for Fapi_NvWrite
117 *
118 * Writes data to a "regular" (not pin, extend or counter) NV index.
119 *
120 * Call Fapi_NvWrite_Finish to finish the execution of this command.
121 *
122 * @param[in,out] context The FAPI_CONTEXT
123 * @param[in] nvPath The path of the NV index to write
124 * @param[in] data The data to write to the NV index
125 * @param[in] size The size of data in bytes
126 *
127 * @retval TSS2_RC_SUCCESS: if the function call was a success.
128 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, nvPath, or data is NULL.
129 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
130 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath is not found.
131 * @retval TSS2_FAPI_RC_NV_EXCEEDED: if the NV is not large enough for the data
132 * to be written.
133 * @retval TSS2_FAPI_RC_NV_WRONG_TYPE: if the NV index is not a "regular" one.
134 * @retval TSS2_FAPI_RC_NV_NOT_WRITEABLE: if the NV is not a writeable index.
135 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN: if the policy is unknown.
136 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
137 * operation already pending.
138 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
139 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
140 * internal operations or return parameters.
141 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
142 * config file.
143 */
144 TSS2_RC
145 Fapi_NvWrite_Async(
146 FAPI_CONTEXT *context,
147 char const *nvPath,
148 uint8_t const *data,
149 size_t size)
150 {
151 LOG_TRACE("called for context:%p", context);
152 LOG_TRACE("nvPath: %s", nvPath);
153 if (data) {
154 LOGBLOB_TRACE(data, size, "data");
155 } else {
156 LOG_TRACE("data: (null) size: %zi", size);
157 }
158
159 TSS2_RC r;
160
161 /* Check for NULL parameters */
162 check_not_null(context);
163 check_not_null(nvPath);
164 check_not_null(data);
165
166 /* Helpful alias pointers */
167 IFAPI_NV_Cmds * command = &context->nv_cmd;
168
169 /* Reset all context-internal session state information. */
170 r = ifapi_session_init(context);
171 return_if_error(r, "Initialize NV_Write");
172
173 /* Initialize the command */
174 uint8_t * commandData = NULL;
175 memset(&context->nv_cmd, 0, sizeof(IFAPI_NV_Cmds));
176 command->offset = 0;
177 command->data = NULL;
178
179
180 /* Copy parameters to context for use during _Finish. */
181 strdup_check(command->nvPath, nvPath, r, error_cleanup);
182
183 commandData = malloc(size);
184 goto_if_null2(commandData, "Out of memory", r, TSS2_FAPI_RC_MEMORY,
185 error_cleanup);
186 memcpy(commandData, data, size);
187 command->data = commandData;
188
189 context->primary_state = PRIMARY_INIT;
190 command->numBytes = size;
191
192 /* Initialize the context state for this operation. */
193 context->state = NV_WRITE_READ;
194 LOG_TRACE("finished");
195 return TSS2_RC_SUCCESS;
196
197 error_cleanup:
198 /* Cleanup duplicated input parameters that were copied before. */
199 SAFE_FREE(command->nvPath);
200 SAFE_FREE(command->data);
201 return r;
202 }
203
204 /** Asynchronous finish function for Fapi_NvWrite
205 *
206 * This function should be called after a previous Fapi_NvWrite.
207 *
208 * @param[in,out] context The FAPI_CONTEXT
209 *
210 * @retval TSS2_RC_SUCCESS: if the function call was a success.
211 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
212 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
213 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
214 * operation already pending.
215 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
216 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
217 * internal operations or return parameters.
218 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
219 * complete. Call this function again later.
220 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
221 * the function.
222 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
223 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
224 * during authorization.
225 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
226 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
227 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
228 * is not set.
229 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
230 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
231 * was not successful.
232 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
233 */
234 TSS2_RC
235 Fapi_NvWrite_Finish(
236 FAPI_CONTEXT *context)
237 {
238 LOG_TRACE("called for context:%p", context);
239
240 TSS2_RC r;
241 json_object *jso = NULL;
242
243 /* Check for NULL parameters */
244 check_not_null(context);
245
246 /* Helpful alias pointers */
247 IFAPI_NV_Cmds * command = &context->nv_cmd;
248
249 switch (context->state) {
250 statecase(context->state, NV_WRITE_READ);
251 /* First check whether the file in object store can be updated. */
252 r = ifapi_keystore_check_writeable(&context->keystore, &context->io, command->nvPath);
253 goto_if_error_reset_state(r, "Check whether update object store is possible.", error_cleanup);
254
255 /* Write to the NV index. */
256 r = ifapi_nv_write(context, command->nvPath, command->offset,
257 command->data, command->numBytes);
258
259 return_try_again(r);
260 goto_if_error_reset_state(r, " FAPI NV Write", error_cleanup);
261
262
263 /* Perform esys serialization if necessary */
264 r = ifapi_esys_serialize_object(context->esys, &command->nv_object);
265 goto_if_error(r, "Prepare serialization", error_cleanup);
266
267 /* Start writing the NV object to the key store */
268 r = ifapi_keystore_store_async(&context->keystore, &context->io,
269 command->nvPath,
270 &command->nv_object);
271 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
272 command->nvPath);
273
274 fallthrough;
275
276 statecase(context->state, NV_WRITE_WRITE);
277 /* Finish writing the NV object to the key store */
278 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
279 return_try_again(r);
280 return_if_error_reset_state(r, "write_finish failed");
281
282 fallthrough;
283
284 statecase(context->state, NV_WRITE_CLEANUP)
285 /* Cleanup the authorization session. */
286 r = ifapi_cleanup_session(context);
287 try_again_or_error_goto(r, "Cleanup", error_cleanup);
288
289 context->state = _FAPI_STATE_INIT;
290 break;
291
292 statecasedefault(context->state);
293 }
294
295 error_cleanup:
296 /* Cleanup any intermediate results and state stored in the context. */
297 ifapi_cleanup_ifapi_object(&command->nv_object);
298 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
299 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
300 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
301 SAFE_FREE(context->nv_cmd.write_data);
302 SAFE_FREE(command->nvPath);
303 SAFE_FREE(command->data);
304 SAFE_FREE(jso);
305 ifapi_session_clean(context);
306
307 LOG_TRACE("finished");
308 return r;
309 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include "tss2_fapi.h"
11 #include "fapi_int.h"
12 #include "fapi_util.h"
13 #include "tss2_esys.h"
14 #include "ifapi_json_serialize.h"
15 #include "fapi_crypto.h"
16 #define LOGMODULE fapi
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20 /** One-Call function for Fapi_PcrExtend
21 *
22 * Performs an extend operation on a given PCR.
23 *
24 * @param[in,out] context The FAPI_CONTEXT
25 * @param[in] pcr The PCR to extend
26 * @param[in] data The data that is to be extended on the PCR
27 * @param[in] dataSize The size of data in bytes
28 * @param[in] logData A JSON representation of data to be written to the PCR's
29 * event log. May be NULL
30 *
31 * @retval TSS2_RC_SUCCESS: if the function call was a success.
32 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or data is NULL.
33 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
34 * @retval TSS2_FAPI_RC_NO_PCR: if no such PCR exists on this TPM.
35 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
36 * operation already pending.
37 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
38 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
39 * internal operations or return parameters.
40 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
41 * config file.
42 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
43 * the function.
44 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
45 * this function needs to be called again.
46 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
47 * during authorization.
48 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
49 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
50 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
51 * is not set.
52 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
53 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
54 * was not successful.
55 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
56 */
57 TSS2_RC
58 Fapi_PcrExtend(
59 FAPI_CONTEXT *context,
60 uint32_t pcr,
61 uint8_t const *data,
62 size_t dataSize,
63 char const *logData)
64 {
65 LOG_TRACE("called for context:%p", context);
66
67 TSS2_RC r, r2;
68
69 /* Check for NULL parameters */
70 check_not_null(context);
71 check_not_null(data);
72
73 /* Check whether TCTI and ESYS are initialized */
74 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
75 TSS2_FAPI_RC_NO_TPM);
76
77 /* If the async state automata of FAPI shall be tested, then we must not set
78 the timeouts of ESYS to blocking mode.
79 During testing, the mssim tcti will ensure multiple re-invocations.
80 Usually however the synchronous invocations of FAPI shall instruct ESYS
81 to block until a result is available. */
82 #ifndef TEST_FAPI_ASYNC
83 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
84 return_if_error_reset_state(r, "Set Timeout to blocking");
85 #endif /* TEST_FAPI_ASYNC */
86
87 r = Fapi_PcrExtend_Async(context, pcr, data, dataSize, logData);
88 return_if_error_reset_state(r, "PcrExtend");
89
90 do {
91 /* We wait for file I/O to be ready if the FAPI state automata
92 are in a file I/O state. */
93 r = ifapi_io_poll(&context->io);
94 return_if_error(r, "Something went wrong with IO polling");
95
96 /* Repeatedly call the finish function, until FAPI has transitioned
97 through all execution stages / states of this invocation. */
98 r = Fapi_PcrExtend_Finish(context);
99 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
100
101 /* Reset the ESYS timeout to non-blocking, immediate response. */
102 r2 = Esys_SetTimeout(context->esys, 0);
103 return_if_error(r2, "Set Timeout to non-blocking");
104
105 return_if_error_reset_state(r, "PcrExtend");
106
107 LOG_TRACE("finished");
108 return TSS2_RC_SUCCESS;
109 }
110
111 /** Asynchronous function for Fapi_PcrExtend
112 *
113 * Performs an extend operation on a given PCR.
114 *
115 * Call Fapi_PcrExtend_Finish to finish the execution of this command.
116 *
117 * @param[in,out] context The FAPI_CONTEXT
118 * @param[in] pcr The PCR to extend
119 * @param[in] data The data that is to be extended on the PCR
120 * @param[in] dataSize The size of data in bytes
121 * @param[in] logData A JSON representation of data to be written to the PCR's
122 * event log. May be NULL
123 *
124 * @retval TSS2_RC_SUCCESS: if the function call was a success.
125 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or data is NULL.
126 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
127 * @retval TSS2_FAPI_RC_NO_PCR: if no such PCR exists on this TPM.
128 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
129 * operation already pending.
130 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
131 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
132 * internal operations or return parameters.
133 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
134 * the function.
135 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
136 * config file.
137 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
138 */
139 TSS2_RC
140 Fapi_PcrExtend_Async(
141 FAPI_CONTEXT *context,
142 uint32_t pcr,
143 uint8_t const *data,
144 size_t dataSize,
145 char const *logData)
146 {
147 LOG_TRACE("called for context:%p", context);
148 LOG_TRACE("pcr: %u", pcr);
149 if (data) {
150 LOGBLOB_TRACE(data, dataSize, "data");
151 } else {
152 LOG_TRACE("data: (null) dataSize: %zi", dataSize);
153 }
154 LOG_TRACE("logData: %s", logData);
155
156 TSS2_RC r;
157
158 /* Check for NULL parameters */
159 check_not_null(context);
160 check_not_null(data);
161
162 /* Helpful alias pointers */
163 IFAPI_PCR * command = &context->cmd.pcr;
164
165 /* Reset all context-internal session state information. */
166 r = ifapi_session_init(context);
167 goto_if_error(r, "Initialize PcrExtend", error_cleanup);
168
169 /* Perform some sanity checks on the input. */
170 if (dataSize > 1024 || dataSize == 0) {
171 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
172 "Event size must be > 1024 and != 0", error_cleanup);
173 }
174
175 /* Copy parameters to context for use during _Finish. */
176 strdup_check(command->logData, logData, r, error_cleanup);
177 command->event.size = dataSize;
178 memcpy(&command->event.buffer[0], data, dataSize);
179 command->pcrIndex = pcr;
180
181 r = Esys_GetCapability_Async(context->esys,
182 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
183 TPM2_CAP_PCRS, 0, 1);
184 goto_if_error(r, "Esys_GetCapability_Async", error_cleanup);
185
186 /* Initialize the context state for this operation. */
187 context->state = PCR_EXTEND_WAIT_FOR_GET_CAP;
188 LOG_TRACE("finished");
189 return TSS2_RC_SUCCESS;
190
191 error_cleanup:
192 /* Cleanup duplicated input parameters that were copied before. */
193 SAFE_FREE(command->logData);
194 return r;
195 }
196
197 /** Asynchronous finish function for Fapi_PcrExtend
198 *
199 * This function should be called after a previous Fapi_PcrExtend_Async.
200 *
201 * @param[in,out] context The FAPI_CONTEXT
202 *
203 * @retval TSS2_RC_SUCCESS: if the function call was a success.
204 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
205 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
206 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
207 * operation already pending.
208 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
209 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
210 * internal operations or return parameters.
211 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
212 * complete. Call this function again later.
213 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
214 * during authorization.
215 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
216 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
217 * the function.
218 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
219 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
220 * is not set.
221 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
222 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
223 * was not successful.
224 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
225 */
226 TSS2_RC
227 Fapi_PcrExtend_Finish(
228 FAPI_CONTEXT *context)
229 {
230 LOG_TRACE("called for context:%p", context);
231
232 TSS2_RC r;
233 TPMI_YES_NO moreData;
234
235 /* Check for NULL parameters */
236 check_not_null(context);
237
238 /* Helpful alias pointers */
239 IFAPI_PCR * command = &context->cmd.pcr;
240 TPMS_CAPABILITY_DATA **capabilityData = &command->capabilityData;
241 IFAPI_EVENT * pcrEvent = &command->pcr_event;
242 IFAPI_TSS_EVENT * subEvent = &pcrEvent->sub_event.tss_event;
243
244 switch (context->state) {
245 statecase(context->state, PCR_EXTEND_WAIT_FOR_GET_CAP);
246 r = Esys_GetCapability_Finish(context->esys, &moreData, capabilityData);
247 return_try_again(r);
248 goto_if_error_reset_state(r, "GetCapablity_Finish", error_cleanup);
249
250 /* Prepare session used for integrity protecting the PCR Event operation. */
251 r = ifapi_get_sessions_async(context,
252 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
253 0, 0);
254 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
255
256 fallthrough;
257
258 statecase(context->state, PCR_EXTEND_WAIT_FOR_SESSION);
259 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
260 context->profiles.default_profile.nameAlg);
261 return_try_again(r);
262 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
263
264 /* Call PCR Event on the TPM, which performs an extend to all banks. */
265 r = Esys_PCR_Event_Async(context->esys, command->pcrIndex,
266 context->session1, ESYS_TR_NONE, ESYS_TR_NONE,
267 &command->event);
268 return_if_error(r, "Esys_PCR_Event_Async");
269 command->event_digests = NULL;
270
271 fallthrough;
272
273 statecase(context->state, PCR_EXTEND_FINISH);
274 r = Esys_PCR_Event_Finish(context->esys, &command->event_digests);
275 return_try_again(r);
276 goto_if_error_reset_state(r, "PCR_Extend_Finish", error_cleanup);
277
278 /* Construct the eventLog entry. */
279 pcrEvent->digests = *command->event_digests;
280 pcrEvent->pcr = command->pcrIndex;
281 pcrEvent->type = IFAPI_TSS_EVENT_TAG;
282 subEvent->data = command->event;
283 if (command->logData) {
284 strdup_check(subEvent->event,
285 command->logData, r, error_cleanup);
286 } else {
287 subEvent->event = NULL;
288 }
289
290 /* Append the eventLog entry to the event log. */
291 r = ifapi_eventlog_append_async(&context->eventlog, &context->io,
292 &command->pcr_event);
293 goto_if_error(r, "Error ifapi_eventlog_append_async", error_cleanup);
294
295 fallthrough;
296
297 statecase(context->state, PCR_EXTEND_APPEND_EVENT_LOG);
298 r = ifapi_eventlog_append_finish(&context->eventlog, &context->io);
299 return_try_again(r);
300 goto_if_error(r, "ifapi_eventlog_append_async", error_cleanup);
301
302 SAFE_FREE(command->event_digests);
303 fallthrough;
304
305 statecase(context->state, PCR_EXTEND_CLEANUP)
306 /* Cleanup the session used for integrity checking. */
307 r = ifapi_cleanup_session(context);
308 try_again_or_error_goto(r, "Cleanup", error_cleanup);
309
310 context->state = _FAPI_STATE_INIT;
311 break;
312
313 statecasedefault(context->state);
314 }
315
316 error_cleanup:
317 /* Cleanup any intermediate results and state stored in the context. */
318 SAFE_FREE(*capabilityData);
319 SAFE_FREE(command->event_digests);
320 SAFE_FREE(command->logData);
321 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
322 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
323 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
324 ifapi_cleanup_event(pcrEvent);
325 ifapi_session_clean(context);
326 LOG_TRACE("finished");
327 return r;
328 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14 #include "fapi_int.h"
15 #include "fapi_util.h"
16 #include "tss2_esys.h"
17 #define LOGMODULE fapi
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** One-Call function for Fapi_PcrRead
22 *
23 * Reads from a given PCR and returns the value and the event log.
24 *
25 * @param[in,out] context The FAPI_CONTEXT
26 * @param[in] pcrIndex The index of the PCR to read
27 * @param[out] pcrValue The value of the PCR. May be NULL
28 * @param[out] pcrValueSize The size of value in bytes. May be NULL
29 * @param[out] pcrLog The PCR log. May be NULL
30 *
31 * @retval TSS2_RC_SUCCESS: if the function call was a success.
32 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, pcrValue or pcrValueSize
33 * is NULL.
34 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
35 * @retval TSS2_FAPI_RC_BAD_VALUE: if pcrIndex is invalid.
36 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
37 * operation already pending.
38 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
39 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
40 * internal operations or return parameters.
41 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
42 * config file.
43 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
44 * this function needs to be called again.
45 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
46 * is not set.
47 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
48 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
49 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
50 * was not successful.
51 * @retval TSS2_FAPI_RC_NO_CERT if an error did occur during certificate downloading.
52 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
53 * during authorization.
54 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
55 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
56 */
57 TSS2_RC
58 Fapi_PcrRead(
59 FAPI_CONTEXT *context,
60 uint32_t pcrIndex,
61 uint8_t **pcrValue,
62 size_t *pcrValueSize,
63 char **pcrLog)
64 {
65 LOG_TRACE("called for context:%p", context);
66
67 TSS2_RC r, r2;
68
69 /* Check for NULL parameters */
70 check_not_null(context);
71
72 /* Check whether TCTI and ESYS are initialized */
73 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
74 TSS2_FAPI_RC_NO_TPM);
75
76 /* If the async state automata of FAPI shall be tested, then we must not set
77 the timeouts of ESYS to blocking mode.
78 During testing, the mssim tcti will ensure multiple re-invocations.
79 Usually however the synchronous invocations of FAPI shall instruct ESYS
80 to block until a result is available. */
81 #ifndef TEST_FAPI_ASYNC
82 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
83 return_if_error_reset_state(r, "Set Timeout to blocking");
84 #endif /* TEST_FAPI_ASYNC */
85
86 r = Fapi_PcrRead_Async(context, pcrIndex);
87 return_if_error_reset_state(r, "PCR_ReadWithLog");
88
89 do {
90 /* We wait for file I/O to be ready if the FAPI state automata
91 are in a file I/O state. */
92 r = ifapi_io_poll(&context->io);
93 return_if_error(r, "Something went wrong with IO polling");
94
95 /* Repeatedly call the finish function, until FAPI has transitioned
96 through all execution stages / states of this invocation. */
97 r = Fapi_PcrRead_Finish(context, pcrValue, pcrValueSize, pcrLog);
98 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
99
100 /* Reset the ESYS timeout to non-blocking, immediate response. */
101 r2 = Esys_SetTimeout(context->esys, 0);
102 return_if_error(r2, "Set Timeout to non-blocking");
103
104 return_if_error_reset_state(r, "NV_ReadWithLog");
105
106 LOG_TRACE("finished");
107 return TSS2_RC_SUCCESS;
108 }
109
110 /** Asynchronous function for Fapi_PcrRead
111 *
112 * Reads from a given PCR and returns the value and the event log.
113 *
114 * Call Fapi_PcrRead_Finish to finish the execution of this command.
115 *
116 * @param[in,out] context The FAPI_CONTEXT
117 * @param[in] pcrIndex The index of the PCR to read
118 *
119 * @retval TSS2_RC_SUCCESS: if the function call was a success.
120 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
121 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
122 * @retval TSS2_FAPI_RC_BAD_VALUE: if pcrIndex is invalid.
123 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
124 * operation already pending.
125 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
126 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
127 * internal operations or return parameters.
128 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
129 * config file.
130 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
131 */
132 TSS2_RC
133 Fapi_PcrRead_Async(
134 FAPI_CONTEXT *context,
135 uint32_t pcrIndex)
136 {
137 LOG_TRACE("called for context:%p", context);
138 LOG_TRACE("pcrIndex: %" PRIu32, pcrIndex);
139
140 TSS2_RC r;
141 TPML_PCR_SELECTION pcr_selection;
142
143 /* Check for NULL parameters */
144 check_not_null(context);
145
146 /* Helpful alias pointers */
147 IFAPI_PCR * command = &context->cmd.pcr;
148
149 /* Reset all context-internal session state information. */
150 r = ifapi_session_init(context);
151 return_if_error(r, "Initialize PcrRead");
152
153 /* Determine the banks to be used for the requested PCR based on
154 the default cryptographic profile. */
155 pcr_selection = context->profiles.default_profile.pcr_selection;
156
157 r = ifapi_filter_pcr_selection_by_index(&pcr_selection, &pcrIndex, 1);
158 return_if_error(r, "PCR selection");
159
160 /* Perform the PCR read operation. */
161 r = Esys_PCR_Read_Async(context->esys,
162 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
163 &pcr_selection);
164 return_if_error(r, "PCR Read");
165
166 /* Used for retrieving the eventlog during finish*/
167 command->pcrIndex = pcrIndex;
168
169 /* Initialize the context state for this operation. */
170 context->state = PCR_READ_READ_PCR;
171
172 LOG_TRACE("finished");
173 return TSS2_RC_SUCCESS;
174 }
175
176 /** Asynchronous finish function for Fapi_PcrRead
177 *
178 * This function should be called after a previous Fapi_PcrRead_Async.
179 *
180 * @param[in,out] context The FAPI_CONTEXT
181 * @param[out] pcrValue The value of the PCR. May be NULL
182 * @param[out] pcrValueSize The size of value in bytes. May be NULL
183 * @param[out] pcrLog The PCR log. May be NULL
184 *
185 * @retval TSS2_RC_SUCCESS: if the function call was a success.
186 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, pcrValue or pcrValueSize
187 * is NULL.
188 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
189 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
190 * operation already pending.
191 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
192 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
193 * internal operations or return parameters.
194 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
195 * complete. Call this function again later.
196 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
197 * the function.
198 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
199 */
200 TSS2_RC
201 Fapi_PcrRead_Finish(
202 FAPI_CONTEXT *context,
203 uint8_t **pcrValue,
204 size_t *pcrValueSize,
205 char **pcrLog)
206 {
207 LOG_TRACE("called for context:%p", context);
208
209 TSS2_RC r;
210
211 /* Check for NULL parameters */
212 check_not_null(context);
213
214 /* Helpful alias pointers */
215 IFAPI_PCR * command = &context->cmd.pcr;
216
217 command->pcrValues = NULL;
218
219 switch (context->state) {
220 statecase(context->state, PCR_READ_READ_PCR);
221 SAFE_FREE(command->pcrValues);
222 r = Esys_PCR_Read_Finish(context->esys,
223 &command->update_count,
224 NULL,
225 &command->pcrValues);
226 return_try_again(r);
227 goto_if_error_reset_state(r, "PCR_ReadWithLog_Finish", cleanup);
228
229 /* Copy the return values to the output parameters. */
230 if (pcrValueSize)
231 *pcrValueSize = command->pcrValues->digests[0].size;
232 if (pcrValue) {
233 *pcrValue = malloc(command->pcrValues->digests[0].size);
234 goto_if_null2(*pcrValue, "Out of memory.",
235 r, TSS2_FAPI_RC_MEMORY, cleanup);
236
237 memcpy(*pcrValue, &command->pcrValues->digests[0].buffer[0],
238 command->pcrValues->digests[0].size);
239 }
240 SAFE_FREE(command->pcrValues);
241
242 /* If no event log was requested the operation is now complete. */
243 if (!pcrLog) {
244 context->state = _FAPI_STATE_INIT;
245 break;
246 }
247
248 /* Retrieve the eventlog for the requestion PCR. */
249 r = ifapi_eventlog_get_async(&context->eventlog, &context->io,
250 &command->pcrIndex, 1);
251 goto_if_error(r, "Error getting event log", cleanup);
252
253 fallthrough;
254
255 statecase(context->state, PCR_READ_READ_EVENT_LIST);
256 r = ifapi_eventlog_get_finish(&context->eventlog, &context->io, pcrLog);
257 return_try_again(r);
258 goto_if_error(r, "Error getting event log", cleanup);
259
260 context->state = _FAPI_STATE_INIT;
261 break;
262
263 statecasedefault(context->state);
264 }
265
266 cleanup:
267 /* Cleanup any intermediate results and state stored in the context. */
268 SAFE_FREE(command->pcrValues);
269 LOG_TRACE("finished");
270 return r;
271 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "fapi_util.h"
17 #include "tss2_tcti.h"
18 #include "tss2_esys.h"
19 #include "tss2_fapi.h"
20 #include "fapi_int.h"
21 #include "fapi_crypto.h"
22 #include "fapi_policy.h"
23 #include "ifapi_get_intl_cert.h"
24
25 #define LOGMODULE fapi
26 #include "util/log.h"
27 #include "util/aux_util.h"
28
29 #define EK_CERT_RANGE (0x01c07fff)
30
31 /** One-Call function for the initial FAPI provisioning.
32 *
33 * Provisions a TSS with its TPM. This includes the setting of important passwords
34 * and policy settings as well as the readout of the EK and its certificate and
35 * the initialization of the system-wide keystore.
36 *
37 * @param[in,out] context The FAPI_CONTEXT.
38 * @param[in] authValueEh The authorization value for the endorsement
39 * hierarchy. May be NULL
40 * @param[in] authValueSh The authorization value for the storage hierarchy.
41 * Should be NULL
42 * @param[in] authValueLockout The authorization value for lockout.
43 *
44 * @retval TSS2_RC_SUCCESS: if the function call was a success.
45 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
46 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
47 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
48 * operation already pending.
49 * @retval TSS2_FAPI_RC_NO_CERT: if no certificate was found for the computed EK.
50 * @retval TSS2_FAPI_RC_BAD_KEY: if public key of the EK does not match the
51 * configured certificate or the configured fingerprint does not match
52 * the computed EK.
53 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
54 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
55 * internal operations or return parameters.
56 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
57 * config file.
58 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
59 * this function needs to be called again.
60 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
61 * the function.
62 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
63 * is not set.
64 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
65 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
66 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
67 * was not successful.
68 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
69 * during authorization.
70 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
71 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
72 */
73 TSS2_RC
74 Fapi_Provision(
75 FAPI_CONTEXT *context,
76 char const *authValueEh,
77 char const *authValueSh,
78 char const *authValueLockout)
79 {
80 LOG_TRACE("called for context:%p", context);
81
82 TSS2_RC r, r2;
83
84 /* Check for NULL parameters */
85 check_not_null(context);
86
87 /* Check whether TCTI and ESYS are initialized */
88 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
89 TSS2_FAPI_RC_NO_TPM);
90
91 /* If the async state automata of FAPI shall be tested, then we must not set
92 the timeouts of ESYS to blocking mode.
93 During testing, the mssim tcti will ensure multiple re-invocations.
94 Usually however the synchronous invocations of FAPI shall instruct ESYS
95 to block until a result is available. */
96 #ifndef TEST_FAPI_ASYNC
97 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
98 return_if_error_reset_state(r, "Set Timeout to blocking");
99 #endif /* TEST_FAPI_ASYNC */
100
101 r = Fapi_Provision_Async(context, authValueEh, authValueSh, authValueLockout);
102 return_if_error_reset_state(r, "Provision");
103
104 do {
105 /* We wait for file I/O to be ready if the FAPI state automata
106 are in a file I/O state. */
107 r = ifapi_io_poll(&context->io);
108 return_if_error(r, "Something went wrong with IO polling");
109
110 /* Repeatedly call the finish function, until FAPI has transitioned
111 through all execution stages / states of this invocation. */
112 r = Fapi_Provision_Finish(context);
113 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
114
115 /* Reset the ESYS timeout to non-blocking, immediate response. */
116 r2 = Esys_SetTimeout(context->esys, 0);
117 return_if_error(r2, "Set Timeout to non-blocking");
118
119 return_if_error_reset_state(r, "Provision");
120
121 LOG_TRACE("finished");
122 return TSS2_RC_SUCCESS;
123 }
124
125 /** Asynchronous function for the initial FAPI provisioning.
126 *
127 * Provisions a TSS with its TPM. This includes the setting of important passwords
128 * and policy settings as well as the readout of the EK and its certificate and
129 * the initialization of the system-wide keystore.
130 *
131 * Call Fapi_Provision_Finish to finish the execution of this command.
132 *
133 * @param[in,out] context The FAPI_CONTEXT.
134 * @param[in] authValueEh The authorization value for the endorsement
135 * hierarchy. May be NULL
136 * @param[in] authValueSh The authorization value for the storage hierarchy.
137 * Should be NULL
138 * @param[in] authValueLockout The authorization value for lockout.
139 *
140 * @retval TSS2_RC_SUCCESS: if the function call was a success.
141 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
142 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
143 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
144 * operation already pending.
145 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
146 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
147 * internal operations or return parameters.
148 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
149 * config file.
150 */
151 TSS2_RC
152 Fapi_Provision_Async(
153 FAPI_CONTEXT *context,
154 char const *authValueEh,
155 char const *authValueSh,
156 char const *authValueLockout)
157 {
158 LOG_TRACE("called for context:%p", context);
159 LOG_TRACE("authValueEh: %s", authValueEh);
160 LOG_TRACE("authValueSh: %s", authValueSh);
161 LOG_TRACE("authValueLockout: %s", authValueLockout);
162
163 TSS2_RC r;
164
165 /* Check for NULL parameters */
166 check_not_null(context);
167
168 /* Helpful alias pointers */
169 IFAPI_Provision * command = &context->cmd.Provision;
170
171 r = ifapi_session_init(context);
172 goto_if_error(r, "Initialize Provision", end);
173
174 /* Initialize context and duplicate parameters */
175 strdup_check(command->authValueLockout, authValueLockout, r, end);
176 strdup_check(command->authValueEh, authValueEh, r, end);
177 strdup_check(command->authValueSh, authValueSh, r, end);
178 context->ek_handle = ESYS_TR_NONE;
179 context->srk_handle = ESYS_TR_NONE;
180 command->cert_nv_idx = MIN_EK_CERT_HANDLE;
181 command->capabilityData = NULL;
182
183 /* Set the initial state for the finish method. */
184 context->state = PROVISION_READ_PROFILE;
185 LOG_TRACE("finished");
186 return TSS2_RC_SUCCESS;
187 end:
188 SAFE_FREE(command->authValueLockout);
189 SAFE_FREE(command->authValueEh);
190 SAFE_FREE(command->authValueSh);
191 return r;
192 }
193
194 /** Asynchronous finish function for Fapi_Provision
195 *
196 * This function should be called after a previous Fapi_Provision_Async.
197 *
198 * @param[in,out] context The FAPI_CONTEXT
199 *
200 * @retval TSS2_RC_SUCCESS: if the function call was a success.
201 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
202 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
203 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
204 * operation already pending.
205 * @retval TSS2_FAPI_RC_NO_CERT: if no certificate was found for the computed EK.
206 * @retval TSS2_FAPI_RC_BAD_KEY: if public key of the EK does not match the
207 * configured certificate or the configured fingerprint does not match
208 * the computed EK.
209 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
210 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
211 * internal operations or return parameters.
212 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
213 * complete. Call this function again later.
214 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
215 * the function.
216 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
217 * is not set.
218 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
219 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
220 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
221 * was not successful.
222 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
223 * during authorization.
224 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
225 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
226 */
227 TSS2_RC
228 Fapi_Provision_Finish(FAPI_CONTEXT *context)
229 {
230 LOG_TRACE("called for context:%p", context);
231
232 TSS2_RC r = TSS2_RC_SUCCESS;
233 TPM2B_NV_PUBLIC *nvPublic = NULL;
234 uint8_t *certData = NULL;
235 size_t certSize;
236 TPMI_YES_NO moreData;
237 size_t hash_size;
238 TPMI_ALG_HASH hash_alg;
239 TPM2B_DIGEST ek_fingerprint;
240
241 /* Check for NULL parameters */
242 check_not_null(context);
243
244 /* Helpful alias pointers */
245 IFAPI_Provision * command = &context->cmd.Provision;
246 IFAPI_OBJECT *hierarchy = &command->hierarchy;
247 TPMS_CAPABILITY_DATA **capabilityData = &command->capabilityData;
248 IFAPI_NV_Cmds * nvCmd = &context->nv_cmd;
249 IFAPI_OBJECT * pkeyObject = &context->createPrimary.pkey_object;
250 IFAPI_KEY * pkey = &pkeyObject->misc.key;
251 IFAPI_PROFILE * defaultProfile = &context->profiles.default_profile;
252 int curl_rc;
253
254 switch (context->state) {
255 statecase(context->state, PROVISION_READ_PROFILE);
256 /*
257 * The default values used for profiling will be used from
258 * the default profile.
259 */
260 command->root_crt = NULL;
261
262 /* Generate template for SRK creation. */
263 r = ifapi_set_key_flags(defaultProfile->srk_template,
264 context->profiles.default_profile.srk_policy ? true : false,
265 &command->public_templ);
266 goto_if_error(r, "Set key flags for SRK", error_cleanup);
267
268 r = ifapi_merge_profile_into_template(&context->profiles.default_profile,
269 &command->public_templ);
270 goto_if_error(r, "Merging profile and template", error_cleanup);
271
272 /* Prepare the setting of the dictionary attack parameters. */
273 r = Esys_DictionaryAttackParameters_Async(context->esys, ESYS_TR_RH_LOCKOUT,
274 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
275 defaultProfile->newMaxTries, defaultProfile->newRecoveryTime,
276 defaultProfile->lockoutRecovery);
277 goto_if_error(r, "Error Esys_DictionaryAttackParameters",
278 error_cleanup);
279 fallthrough;
280
281 statecase(context->state, PROVISION_WRITE_LOCKOUT_PARAM);
282 r = Esys_DictionaryAttackParameters_Finish(context->esys);
283 return_try_again(r);
284 goto_if_error_reset_state(r, "DictionaryAttackParameters_Finish",
285 error_cleanup);
286
287 /* Prepare the command for reading the TPMs PCR capabilities. */
288 r = Esys_GetCapability_Async(context->esys,
289 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, TPM2_CAP_PCRS, 0, 1);
290 goto_if_error(r, "Esys_GetCapability_Async", error_cleanup);
291
292 fallthrough;
293
294 statecase(context->state, PROVISION_WAIT_FOR_GET_CAP1);
295 r = Esys_GetCapability_Finish(context->esys, &moreData, capabilityData);
296 return_try_again(r);
297 goto_if_error_reset_state(r, "GetCapablity_Finish", error_cleanup);
298
299 /* Check whether the TPMs PCR capabilities are compatible with the profile. */
300 TPML_PCR_SELECTION pcr_capability = (*capabilityData)->data.assignedPCR;
301 r = ifapi_check_profile_pcr_selection(&defaultProfile->pcr_selection,
302 &pcr_capability);
303 goto_if_error(r, "Invalid PCR selection in profile.", error_cleanup);
304
305 SAFE_FREE(*capabilityData);
306 fallthrough;
307
308 statecase(context->state, PROVISION_INIT_SRK);
309 /* Clear key object for the primary to be created */
310 memset(pkey, 0, sizeof(IFAPI_KEY));
311
312 /* Prepare the SRK generation. */
313 r = ifapi_init_primary_async(context, TSS2_SRK);
314 goto_if_error(r, "Initialize primary", error_cleanup);
315
316 context->state = PROVISION_AUTH_SRK_NO_AUTH_SENT;
317 fallthrough;
318
319 statecase(context->state, PROVISION_AUTH_SRK_AUTH_SENT);
320 fallthrough;
321
322 statecase(context->state, PROVISION_AUTH_SRK_NO_AUTH_SENT);
323 r = ifapi_init_primary_finish(context, TSS2_SRK);
324 return_try_again(r);
325 goto_if_error(r, "Init primary finish.", error_cleanup);
326
327 /* Check whether a persistent SRK handle was defined in profile. */
328 if (command->public_templ.persistent_handle) {
329 /* Assign found handle to object */
330 pkey->persistent_handle = command->public_templ.persistent_handle;
331
332 /* Initialize hierarchy object used for evict control. */
333 ifapi_init_hierarchy_object(hierarchy, ESYS_TR_RH_OWNER);
334
335 /* Prepare making the SRK permanent. */
336 r = Esys_EvictControl_Async(context->esys, hierarchy->handle,
337 pkeyObject->handle, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
338 pkey->persistent_handle);
339 goto_if_error(r, "Error Esys EvictControl", error_cleanup);
340
341 context->state = PROVISION_WAIT_FOR_SRK_PERSISTENT;
342 return TSS2_FAPI_RC_TRY_AGAIN;
343 }
344 /* No further ESYS command is needed, the keystore object can be written. */
345 context->state = PROVISION_SRK_WRITE_PREPARE;
346 fallthrough;
347
348 statecase(context->state, PROVISION_SRK_WRITE_PREPARE);
349 pkeyObject->objectType = IFAPI_KEY_OBJ;
350 pkeyObject->system = command->public_templ.system;
351
352 /* Perform esys serialization if necessary */
353 r = ifapi_esys_serialize_object(context->esys, pkeyObject);
354 goto_if_error(r, "Prepare serialization", error_cleanup);
355
356 /* Start writing the SRK to the key store */
357 r = ifapi_keystore_store_async(&context->keystore, &context->io, "HS/SRK",
358 pkeyObject);
359 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup, "HS/SRK");
360 context->state = PROVISION_SRK_WRITE;
361 fallthrough;
362
363 statecase(context->state, PROVISION_SRK_WRITE);
364 /* Finish writing the SRK to the key store */
365 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
366 return_try_again(r);
367 goto_if_error_reset_state(r, "write_finish failed", error_cleanup);
368
369 /* Clean objects used for SRK computation */
370 ifapi_cleanup_ifapi_object(pkeyObject);
371 memset(&command->public_templ, 0, sizeof(IFAPI_KEY_TEMPLATE));
372
373 /* Generate template for EK creation. */
374 r = ifapi_set_key_flags(defaultProfile->ek_template,
375 context->profiles.default_profile.ek_policy ? true : false,
376 &command->public_templ);
377 goto_if_error(r, "Set key flags for SRK", error_cleanup);
378
379 r = ifapi_merge_profile_into_template(&context->profiles.default_profile,
380 &command->public_templ);
381 goto_if_error(r, "Merging profile", error_cleanup);
382
383 /* Clear key object for the primary to be created */
384 memset(pkey, 0, sizeof(IFAPI_KEY));
385
386 /* Prepare the EK generation. */
387 r = ifapi_init_primary_async(context, TSS2_EK);
388 goto_if_error(r, "Initialize primary", error_cleanup);
389 fallthrough;
390 statecase(context->state, PROVISION_AUTH_EK_AUTH_SENT);
391 fallthrough;
392
393 statecase(context->state, PROVISION_AUTH_EK_NO_AUTH_SENT);
394 r = ifapi_init_primary_finish(context, TSS2_EK);
395 return_try_again(r);
396 goto_if_error(r, "Init primary finish", error_cleanup);
397
398 /* Check whether a persistent EK handle was defined in profile. */
399 if (command->public_templ.persistent_handle) {
400
401 /* Initialize hierarchy object used for EK processing. */
402 ifapi_init_hierarchy_object(hierarchy, ESYS_TR_RH_OWNER);
403
404 pkey->persistent_handle = command->public_templ.persistent_handle;
405
406 /* Prepare making the EK permanent. */
407 r = Esys_EvictControl_Async(context->esys, hierarchy->handle,
408 pkeyObject->handle, ESYS_TR_PASSWORD, ESYS_TR_NONE,
409 ESYS_TR_NONE, pkey->persistent_handle);
410 goto_if_error(r, "Error Esys EvictControl", error_cleanup);
411 context->state = PROVISION_WAIT_FOR_EK_PERSISTENT;
412 return TSS2_FAPI_RC_TRY_AGAIN;
413 }
414 fallthrough;
415
416 statecase(context->state, PROVISION_INIT_GET_CAP2);
417 if (context->config.ek_cert_less == TPM2_YES) {
418 /* Skip certificate validation. */
419 context->state = PROVISION_EK_WRITE_PREPARE;
420 return TSS2_FAPI_RC_TRY_AGAIN;
421 }
422
423 /* Check whether fingerprint for EK is defined in config file. */
424 hash_alg = context->config.ek_fingerprint.hashAlg;
425 if (hash_alg) {
426 LOG_DEBUG("Only fingerprint check for EK.");
427 if (!(hash_size =ifapi_hash_get_digest_size(hash_alg))) {
428 goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED,
429 "Unsupported hash algorithm (%" PRIu16 ")", error_cleanup,
430 hash_alg);
431 }
432 r = ifapi_get_tpm_key_fingerprint(&pkeyObject->misc.key.public, hash_alg,
433 &ek_fingerprint);
434 goto_if_error_reset_state(r, "Get fingerprint of EK", error_cleanup);
435
436 if (hash_size != ek_fingerprint.size ||
437 memcmp(&context->config.ek_fingerprint.digest, &ek_fingerprint.buffer[0],
438 hash_size) != 0) {
439 goto_error(r, TSS2_FAPI_RC_BAD_KEY,
440 "Fingerprint of EK not equal to fingerprint in config file.",
441 error_cleanup);
442 }
443 /* The fingerprint was found no further certificate processing needed. */
444 context->state = PROVISION_EK_WRITE_PREPARE;
445 return TSS2_FAPI_RC_TRY_AGAIN;
446 }
447
448 /* Check whether EK certificate has to be retrieved */
449 if (context->config.ek_cert_file) {
450 size_t cert_size;
451 TPM2B_PUBLIC public_key;
452
453 /* Curl will be used to retrieve the certificate from a file or via HTTP. */
454 curl_rc = ifapi_get_curl_buffer((unsigned char *)context->config.ek_cert_file,
455 (unsigned char **)&command->pem_cert, &cert_size);
456 if (curl_rc != 0) {
457 goto_error_reset_state(r, TSS2_FAPI_RC_NO_CERT, "Get certificate.",
458 error_cleanup);
459 }
460
461 /* Get the public key from the certificate. */
462 r = ifapi_get_public_from_pem_cert(command->pem_cert, &public_key);
463 goto_if_error_reset_state(r, "Get public key from pem certificate",
464 error_cleanup);
465 /* Compare public key of certificate with public data of EK */
466 if (ifapi_cmp_public_key(&pkeyObject->misc.key.public, &public_key)) {
467 /* The retrieved certificate will be written to keystore,
468 no further certificate processing needed. */
469 context->state = PROVISION_EK_WRITE_PREPARE;
470 return TSS2_FAPI_RC_TRY_AGAIN;
471 }
472 goto_error(r, TSS2_FAPI_RC_BAD_KEY,
473 "Public key of EK does not match certificate.",
474 error_cleanup);
475 }
476
477 /* Prepare the search for certificates store in the NV ram of the TPM. */
478 r = Esys_GetCapability_Async(context->esys,
479 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, TPM2_CAP_HANDLES,
480 MIN_EK_CERT_HANDLE, TPM2_MAX_CAP_HANDLES);
481 goto_if_error(r, "Esys_GetCapability_Async", error_cleanup);
482
483 fallthrough;
484
485 statecase(context->state, PROVISION_WAIT_FOR_GET_CAP2);
486 r = Esys_GetCapability_Finish(context->esys, &moreData, capabilityData);
487 return_try_again(r);
488 goto_if_error_reset_state(r, "GetCapablity_Finish", error_cleanup);
489
490 if ((*capabilityData)->data.handles.count == 0) {
491 /* No more certificate, the EK can be compared with the certificates. */
492 Esys_Free(*capabilityData);
493 context->state = PROVISION_CHECK_FOR_VENDOR_CERT;
494 return TSS2_FAPI_RC_TRY_AGAIN;
495 }
496 command->capabilityData = *capabilityData;
497 command->cert_count = (*capabilityData)->data.handles.count;
498
499 /* Filter out NV handles beyond the EK cert range */
500 for (size_t i = 0; i < command->cert_count; i++) {
501 if (command->capabilityData->data.handles.handle[i] > EK_CERT_RANGE) {
502 command->cert_count = i;
503 }
504 }
505
506 if (command->cert_count == 0) {
507 /* No certificates were found the cert range. */
508 Esys_Free(command->capabilityData);
509 command->capabilityData = NULL;
510 context->state = PROVISION_CHECK_FOR_VENDOR_CERT;
511 return TSS2_FAPI_RC_TRY_AGAIN;
512 }
513 fallthrough;
514
515 statecase(context->state, PROVISION_GET_CERT_NV);
516
517 /* Detemine the NV index of the certifcate from the read capability data. */
518 command->cert_nv_idx
519 = command->capabilityData->data.handles.handle[command->cert_count-1];
520
521 if ((command->cert_nv_idx % 2) || /**< Certificates will be stored at even address */
522 command->cert_nv_idx == 0x01c00004 || /**< RSA template */
523 command->cert_nv_idx == 0x01c0000c) { /**< ECC template */
524 if (command->cert_count > 1) {
525 command->cert_count -= 1;
526 /* Check next certificate */
527 context->state = PROVISION_GET_CERT_NV;
528 return TSS2_FAPI_RC_TRY_AGAIN;
529 } else {
530 /* All certificates have been read, the EK can be written. */
531 context->state = PROVISION_EK_WRITE_PREPARE;
532 return TSS2_FAPI_RC_TRY_AGAIN;
533 }
534 }
535 ifapi_init_hierarchy_object(&nvCmd->auth_object, TPM2_RH_OWNER);
536
537 /* Create esys object for the NV object of the certificate. */
538 r = Esys_TR_FromTPMPublic_Async(context->esys, command->cert_nv_idx,
539 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE);
540 goto_if_error_reset_state(r, "Esys_TR_FromTPMPublic_Async", error_cleanup);
541
542 context->state = PROVISION_GET_CERT_NV_FINISH;
543 fallthrough;
544
545 statecase(context->state, PROVISION_GET_CERT_NV_FINISH);
546 r = Esys_TR_FromTPMPublic_Finish(context->esys,
547 &command->esys_nv_cert_handle);
548 return_try_again(r);
549 goto_if_error_reset_state(r, "TR_FromTPMPublic_Finish", error_cleanup);
550
551 /* Read public to get size of certificate */
552 r = Esys_NV_ReadPublic_Async(context->esys, command->esys_nv_cert_handle,
553 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE);
554 goto_if_error_reset_state(r, "Esys_NV_ReadPublic_Async", error_cleanup);
555
556 context->state = PROVISION_GET_CERT_READ_PUBLIC;
557 fallthrough;
558
559 statecase(context->state, PROVISION_GET_CERT_READ_PUBLIC);
560 r = Esys_NV_ReadPublic_Finish(context->esys, &nvPublic, NULL);
561 return_try_again(r);
562
563 goto_if_error(r, "Error: nv read public", error_cleanup);
564
565 /* TPMA_NV_NO_DA is set for NV certificate */
566 nvCmd->nv_object.misc.nv.public.nvPublic.attributes = TPMA_NV_NO_DA;
567
568 /* Prepare context for nv read */
569 nvCmd->data_idx = 0;
570 nvCmd->auth_index = ESYS_TR_RH_OWNER;
571 nvCmd->numBytes = nvPublic->nvPublic.dataSize;
572 nvCmd->esys_handle = command->esys_nv_cert_handle;
573 nvCmd->offset = 0;
574 command->pem_cert = NULL;
575 context->session1 = ESYS_TR_PASSWORD;
576 context->session2 = ESYS_TR_NONE;
577 nvCmd->nv_read_state = NV_READ_INIT;
578 memset(&nvCmd->nv_object, 0, sizeof(IFAPI_OBJECT));
579 SAFE_FREE(nvPublic);
580
581 context->state = PROVISION_READ_CERT;
582 fallthrough;
583
584 statecase(context->state, PROVISION_READ_CERT);
585 TPM2B_PUBLIC public_key;
586 char * root_ca_file;
587
588 /* The NV object of the certificate will be read asynchronous. */
589 r = ifapi_nv_read(context, &certData, &certSize);
590 return_try_again(r);
591 goto_if_error_reset_state(r, " FAPI NV_Read", error_cleanup);
592
593 /* For storage in key store the certificate will be converted to PEM. */
594 r = ifapi_cert_to_pem(certData, certSize, &command->pem_cert,
595 &command->cert_key_type, &public_key);
596 SAFE_FREE(certData);
597 goto_if_error(r, "Convert certificate to pem.", error_cleanup);
598
599 /* Check whether the EKs public key corresponds to the certificate. */
600 if (ifapi_cmp_public_key(&pkeyObject->misc.key.public, &public_key)) {
601 context->state = PROVISION_PREPARE_READ_ROOT_CERT;
602 return TSS2_FAPI_RC_TRY_AGAIN;
603 } else {
604 /* Certificate not appropriate for current EK key type */
605 command->cert_count -= 1;
606 SAFE_FREE(command->pem_cert);
607 if (command->cert_count > 0) {
608 /* Check next certificate */
609 context->state = PROVISION_GET_CERT_NV;
610 return TSS2_FAPI_RC_TRY_AGAIN;
611 }
612 }
613
614 goto_error(r, TSS2_FAPI_RC_NO_CERT, "No EK certificate found.",
615 error_cleanup);
616
617 statecase(context->state, PROVISION_PREPARE_READ_ROOT_CERT);
618 /* Prepare reading of root certificate. */
619 root_ca_file = getenv("FAPI_TEST_ROOT_CERT");
620 if (!root_ca_file) {
621 context->state = PROVISION_EK_CHECK_CERT;
622 return TSS2_FAPI_RC_TRY_AGAIN;
623 }
624 r = ifapi_io_read_async(&context->io, root_ca_file);
625 return_try_again(r);
626 goto_if_error2(r, "Reading certificate %s", error_cleanup, root_ca_file);
627
628 fallthrough;
629
630 statecase(context->state, PROVISION_READ_ROOT_CERT);
631 r = ifapi_io_read_finish(&context->io, (uint8_t **) &command->root_crt, NULL);
632 return_try_again(r);
633 goto_if_error(r, "Reading root certificate failed", error_cleanup);
634
635 fallthrough;
636
637 statecase(context->state, PROVISION_EK_CHECK_CERT);
638 /* The EK certificate will be verified against the FAPI list of root certificates. */
639 r = ifapi_verify_ek_cert(command->root_crt, command->intermed_crt, command->pem_cert);
640 SAFE_FREE(command->root_crt);
641 SAFE_FREE(command->intermed_crt);
642 goto_if_error2(r, "Verify EK certificate", error_cleanup);
643
644 fallthrough;
645
646 statecase(context->state, PROVISION_EK_WRITE_PREPARE);
647 pkeyObject->objectType = IFAPI_KEY_OBJ;
648 pkeyObject->system = command->public_templ.system;
649 strdup_check(pkeyObject->misc.key.certificate, command->pem_cert, r, error_cleanup);
650 SAFE_FREE(command->pem_cert);
651
652 /* Perform esys serialization if necessary */
653 r = ifapi_esys_serialize_object(context->esys,
654 pkeyObject);
655 goto_if_error(r, "Prepare serialization", error_cleanup);
656
657 /* Start writing the EK to the key store */
658 r = ifapi_keystore_store_async(&context->keystore, &context->io, "HE/EK",
659 pkeyObject);
660 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup, "HE/EK");
661
662 fallthrough;
663
664 statecase(context->state, PROVISION_EK_WRITE);
665 /* Finish writing the EK to the key store */
666 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
667 return_try_again(r);
668 goto_if_error_reset_state(r, "write_finish failed", error_cleanup);
669
670 /* Clean objects used for EK computation */
671 ifapi_cleanup_ifapi_object(pkeyObject);
672 memset(&command->public_templ, 0, sizeof(IFAPI_KEY_TEMPLATE));
673 SAFE_FREE(hierarchy->misc.hierarchy.description);
674
675 /*
676 * Adaption of the lockout hierarchy to the passed parameters
677 * and the current profile.
678 */
679 ifapi_init_hierarchy_object(hierarchy, ESYS_TR_RH_LOCKOUT);
680 strdup_check(hierarchy->misc.hierarchy.description, "Lockout Hierarchy",
681 r, error_cleanup);
682
683 if (!command->authValueLockout ||
684 strcmp(command->authValueLockout, "") == 0) {
685 context->state = PROVISION_LOCKOUT_CHANGE_POLICY;
686 /* Auth value of lockout hierarchy will not be changed. */
687 return TSS2_FAPI_RC_TRY_AGAIN;
688 }
689
690 if (strlen(command->authValueLockout) > sizeof(TPMU_HA)) {
691 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
692 "Password too long.", error_cleanup);
693 }
694 /* Copy auth value into context. */
695 memcpy(&command->hierarchy_auth.buffer[0],
696 command->authValueLockout, strlen(command->authValueLockout));
697 command->hierarchy_auth.size = strlen(command->authValueLockout);
698 context->state = PROVISION_CHANGE_LOCKOUT_AUTH;
699 return TSS2_FAPI_RC_TRY_AGAIN;
700
701 statecase(context->state, PROVISION_WAIT_FOR_SRK_PERSISTENT);
702 r = Esys_EvictControl_Finish(context->esys, &pkeyObject->handle);
703 return_try_again(r);
704 goto_if_error(r, "Evict control failed", error_cleanup);
705
706 /* The SRK was made persistent and can be written to key store. */
707 context->state = PROVISION_SRK_WRITE_PREPARE;
708 return TSS2_FAPI_RC_TRY_AGAIN;
709
710 statecase(context->state, PROVISION_WAIT_FOR_EK_PERSISTENT);
711 r = Esys_EvictControl_Finish(context->esys, &pkeyObject->handle);
712 return_try_again(r);
713 goto_if_error(r, "Evict control failed", error_cleanup);
714
715 context->state = PROVISION_INIT_GET_CAP2;
716 return TSS2_FAPI_RC_TRY_AGAIN;
717
718 statecase(context->state, PROVISION_CHANGE_LOCKOUT_AUTH);
719
720 /* If a lockout auth value is provided by profile, the auth value
721 if the hierarchy will be changed asynchronous. */
722 r = ifapi_change_auth_hierarchy(context, ESYS_TR_RH_LOCKOUT,
723 &command->hierarchy, &command->hierarchy_auth);
724 return_try_again(r);
725 goto_if_error(r, "Change auth hierarchy.", error_cleanup);
726
727 context->state = PROVISION_LOCKOUT_CHANGE_POLICY;
728 fallthrough;
729
730 statecase(context->state, PROVISION_LOCKOUT_CHANGE_POLICY);
731 /* If a lockout policy is provided by profile, the policy will be
732 assigned to lockout hierarchy asynchronous. */
733 r = ifapi_change_policy_hierarchy(context, ESYS_TR_RH_LOCKOUT,
734 hierarchy, defaultProfile->lockout_policy);
735 return_try_again(r);
736 goto_if_error(r, "Change policy LOCKOUT", error_cleanup);
737
738 /* Start writing the lockout hierarchy object to the key store */
739 r = ifapi_keystore_store_async(&context->keystore, &context->io, "/LOCKOUT",
740 &command->hierarchy);
741 goto_if_error_reset_state(r, "Could not open: %sh",
742 error_cleanup, "/LOCKOUT");
743
744 context->state = PROVISION_WRITE_LOCKOUT;
745 fallthrough;
746
747 statecase(context->state, PROVISION_WRITE_LOCKOUT);
748 /* Finish writing the lockout hierarchy to the key store */
749 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
750 return_try_again(r);
751 goto_if_error_reset_state(r, "write_finish failed", error_cleanup);
752
753 SAFE_FREE(hierarchy->misc.hierarchy.description);
754
755 /*
756 * Adaption of the Endorsement hierarchy to the passed parameters
757 * and the current profile.
758 */
759 ifapi_init_hierarchy_object(hierarchy, ESYS_TR_RH_ENDORSEMENT);
760 strdup_check(hierarchy->misc.hierarchy.description,
761 "Endorsement Hierarchy", r, error_cleanup);
762
763 context->state = PROVISION_CHANGE_EH_CHECK;
764 fallthrough;
765
766 statecase(context->state, PROVISION_CHANGE_EH_CHECK);
767 if (command->authValueEh) {
768 context->state = PROVISION_CHANGE_EH_AUTH;
769 /* Save auth value of endorsement hierarchy in context. */
770 memcpy(&command->hierarchy_auth.buffer[0], command->authValueEh,
771 strlen(command->authValueEh));
772 command->hierarchy_auth.size = strlen(command->authValueEh);
773 } else {
774 /* Auth value of lockout hierarchy will not be changed. */
775 context->state = PROVISION_EH_CHANGE_POLICY;
776 return TSS2_FAPI_RC_TRY_AGAIN;
777 }
778 context->state = PROVISION_CHANGE_EH_AUTH;
779 fallthrough;
780
781 statecase(context->state, PROVISION_CHANGE_EH_AUTH);
782 /* If an endorsement hierarchy auth value is provided by profile,
783 the auth value will be changed asynchronous. */
784 r = ifapi_change_auth_hierarchy(context, ESYS_TR_RH_ENDORSEMENT,
785 &command->hierarchy, &command->hierarchy_auth);
786 return_try_again(r);
787 goto_if_error(r, "Change auth hierarchy.", error_cleanup);
788
789 context->state = PROVISION_EH_CHANGE_POLICY;
790 fallthrough;
791
792 statecase(context->state, PROVISION_EH_CHANGE_POLICY);
793 /* If an endorsement hierarchy policy is provided by profile,
794 the policy will be assigned asynchronous. */
795 r = ifapi_change_policy_hierarchy(context, ESYS_TR_RH_ENDORSEMENT,
796 hierarchy, defaultProfile->eh_policy);
797 return_try_again(r);
798 goto_if_error(r, "Change policy EH", error_cleanup);
799
800 /* Start writing the endorsement hierarchy object to the key store */
801 r = ifapi_keystore_store_async(&context->keystore, &context->io, "/HE",
802 &command->hierarchy);
803 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup, "/HE");
804
805 context->state = PROVISION_WRITE_EH;
806 fallthrough;
807
808 statecase(context->state, PROVISION_WRITE_EH);
809 /* Finish writing the endorsement hierarchy to the key store */
810 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
811 return_try_again(r);
812 return_if_error_reset_state(r, "write_finish failed");
813
814 SAFE_FREE(hierarchy->misc.hierarchy.description);
815
816 /*
817 * Adaption of the owner hierarchy to the passed parameters
818 * and the current profile.
819 */
820 ifapi_init_hierarchy_object(hierarchy, ESYS_TR_RH_OWNER);
821 strdup_check(hierarchy->misc.hierarchy.description,
822 "Owner Hierarchy", r, error_cleanup);
823
824 context->state = PROVISION_CHANGE_SH_CHECK;
825 fallthrough;
826
827 statecase(context->state, PROVISION_CHANGE_SH_CHECK);
828 if (command->authValueSh) {
829 context->state = PROVISION_CHANGE_SH_AUTH;
830 /* Save auth value of owner hierarchy in context. */
831 memcpy(&command->hierarchy_auth.buffer[0], command->authValueSh,
832 strlen(command->authValueSh));
833 command->hierarchy_auth.size = strlen(command->authValueSh);
834 context->state = PROVISION_CHANGE_SH_AUTH;
835 } else {
836 /* Auth value of owner hierarchy will not be changed. */
837 context->state = PROVISION_SH_CHANGE_POLICY;
838 return TSS2_FAPI_RC_TRY_AGAIN;
839 }
840 context->state = PROVISION_CHANGE_SH_AUTH;
841 fallthrough;
842
843 statecase(context->state, PROVISION_CHANGE_SH_AUTH);
844 /* If an owner hierarchy auth value is provided by profile,
845 the auth value will be changed asynchronous. */
846 r = ifapi_change_auth_hierarchy(context, ESYS_TR_RH_OWNER,
847 &command->hierarchy, &command->hierarchy_auth);
848 return_try_again(r);
849 goto_if_error(r, "Change auth hierarchy.", error_cleanup);
850
851 context->state = PROVISION_SH_CHANGE_POLICY;
852 fallthrough;
853
854 statecase(context->state, PROVISION_SH_CHANGE_POLICY);
855 /* If an owner hierarchy policy is provided by profile,
856 the policy will be assigned asynchronous. */
857 r = ifapi_change_policy_hierarchy(context, ESYS_TR_RH_OWNER,
858 hierarchy, defaultProfile->sh_policy);
859 return_try_again(r);
860 goto_if_error(r, "Change policy SH", error_cleanup);
861
862 /* Start writing the owner hierarchy object to the key store */
863 r = ifapi_keystore_store_async(&context->keystore, &context->io, "/HS",
864 &command->hierarchy);
865 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup, "/HS");
866 context->state = PROVISION_WRITE_SH;
867 fallthrough;
868
869 statecase(context->state, PROVISION_WRITE_SH);
870 /* The onwer hierarchy object will be written to key store. */
871 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
872 return_try_again(r);
873 goto_if_error_reset_state(r, "write_finish failed", error_cleanup);
874 fallthrough;
875
876 statecase(context->state, PROVISION_FINISHED);
877 if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
878 /* Prepare the flushing of a non persistent SRK. */
879 r = Esys_FlushContext_Async(context->esys, context->srk_handle);
880 goto_if_error(r, "Flush SRK", error_cleanup);
881 }
882 fallthrough;
883
884 /* Flush the SRK if not persistent */
885 statecase(context->state, PROVISION_FLUSH_SRK);
886 if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
887 r = Esys_FlushContext_Finish(context->esys);
888 try_again_or_error_goto(r, "Flush SRK", error_cleanup);
889
890 context->srk_handle = ESYS_TR_NONE;
891
892 }
893 if (!context->ek_persistent && context->ek_handle != ESYS_TR_NONE) {
894 /* Prepare the flushing of a non persistent EK. */
895 r = Esys_FlushContext_Async(context->esys, context->ek_handle);
896 goto_if_error(r, "Flush EK", error_cleanup);
897 }
898 fallthrough;
899
900 /* Flush the EK if not persistent */
901 statecase(context->state, PROVISION_FLUSH_EK);
902 if (!context->ek_persistent && context->ek_handle != ESYS_TR_NONE) {
903 r = Esys_FlushContext_Finish(context->esys);
904 try_again_or_error_goto(r, "Flush EK", error_cleanup);
905
906 context->ek_handle = ESYS_TR_NONE;
907 }
908
909 context->state = _FAPI_STATE_INIT;
910 break;
911
912 /*
913 * The vendor ID stored in the TPM has to be read to check whether
914 * a special certificate handling is needed.
915 */
916 statecase(context->state, PROVISION_CHECK_FOR_VENDOR_CERT);
917 /* Prepare reading the vendor ID */
918 r = Esys_GetCapability_Async(context->esys,
919 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
920 TPM2_CAP_TPM_PROPERTIES, TPM2_PT_MANUFACTURER, 1);
921 goto_if_error(r, "Esys_GetCapability_Async", error_cleanup);
922
923 fallthrough;
924
925 statecase(context->state, PROVISION_GET_VENDOR);
926 /* Get the vendor ID asynchronous. */
927 r = Esys_GetCapability_Finish(context->esys, &moreData, capabilityData);
928 return_try_again(r);
929 goto_if_error_reset_state(r, "GetCapablity_Finish", error_cleanup);
930
931 if ((*capabilityData)->data.tpmProperties.tpmProperty[0].value == VENDOR_INTC) {
932 /* Get INTEL certificate for EK public hash via web */
933 uint8_t *cert_buffer = NULL;
934 size_t cert_size;
935 TPM2B_PUBLIC public;
936 r = ifapi_get_intl_ek_certificate(context, &pkey->public, &cert_buffer,
937 &cert_size);
938 goto_if_error_reset_state(r, "Get certificates", error_cleanup);
939
940 r = ifapi_cert_to_pem(cert_buffer, cert_size, &command->pem_cert,
941 NULL, &public);
942 SAFE_FREE(cert_buffer);
943 goto_if_error_reset_state(r, "Convert certificate buffer to PEM.",
944 error_cleanup);
945 }
946 SAFE_FREE(*capabilityData);
947 context->state = PROVISION_EK_WRITE_PREPARE;
948 return TSS2_FAPI_RC_TRY_AGAIN;
949
950 statecasedefault(context->state);
951 }
952
953 error_cleanup:
954 /* Primaries might not have been flushed in error cases */
955 ifapi_primary_clean(context);
956 SAFE_FREE(command->root_crt);
957 SAFE_FREE(*capabilityData);
958 SAFE_FREE(hierarchy->misc.hierarchy.description);
959 SAFE_FREE(command->authValueLockout);
960 SAFE_FREE(command->authValueEh);
961 SAFE_FREE(command->authValueSh);
962 SAFE_FREE(command->pem_cert);
963 SAFE_FREE(certData);
964 SAFE_FREE(nvPublic);
965 LOG_TRACE("finished");
966 return r;
967 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14 #include "fapi_int.h"
15 #include "fapi_util.h"
16 #include "tss2_esys.h"
17 #define LOGMODULE fapi
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** One-Call function for Fapi_Quote
22 *
23 * Given a set of PCRs and a restricted signing key, it will sign those PCRs and
24 * return the quote.
25 *
26 * @param[in,out] context The FAPI_CONTEXT
27 * @param[in] pcrList The list of PCRs that are to be quoted
28 * @param[in] pcrListSize The size of pcrList in bytes
29 * @param[in] keyPath The path to the signing key
30 * @param[in] quoteType The type of quote. May be NULL
31 * @param[in] qualifyingData A nonce provided by the caller. May be NULL
32 * @param[in] qualifyingDataSize The size of qualifyingData in bytes. Must be 0
33 * if qualifyingData is NULL
34 * @param[out] quoteInfo A JSON-encoded structure holding the inputs to the
35 * quote operation
36 * @param[out] signature The signature of the PCRs
37 * @param[out] signatureSize The size of the signature in bytes. May be NULL
38 * @param[out] pcrLog The log of the PCR. May be NULL
39 * @param[out] certificate The certificate associated with the signing key. May
40 * be NULL
41 *
42 * @retval TSS2_RC_SUCCESS: if the function call was a success.
43 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, pcrList, keyPath,
44 * quoteInfo or signature is NULL.
45 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
46 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if path does not map to a FAPI entity.
47 * @retval TSS2_FAPI_RC_BAD_KEY: if the entity at path is not a key, or is a key
48 * that is unsuitable for the requested operation.
49 * @retval TSS2_FAPI_RC_BAD_VALUE: if qualifyingData is invalid or if
50 * qualifyingDataSize is zero.
51 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
52 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
53 * operation already pending.
54 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
55 * internal operations or return parameters.
56 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
57 * config file.
58 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
59 * this function needs to be called again.
60 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
61 * during authorization.
62 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
63 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
64 * is not set.
65 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
66 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
67 * was not successful.
68 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
69 */
70 TSS2_RC
71 Fapi_Quote(
72 FAPI_CONTEXT *context,
73 uint32_t *pcrList,
74 size_t pcrListSize,
75 char const *keyPath,
76 char const *quoteType,
77 uint8_t const *qualifyingData,
78 size_t qualifyingDataSize,
79 char **quoteInfo,
80 uint8_t **signature,
81 size_t *signatureSize,
82 char **pcrLog,
83 char **certificate)
84 {
85 LOG_TRACE("called for context:%p", context);
86
87 TSS2_RC r, r2;
88
89 /* Check for NULL parameters */
90 check_not_null(context);
91 check_not_null(pcrList);
92 check_not_null(keyPath);
93 check_not_null(quoteInfo);
94 check_not_null(signature);
95
96 /* Check whether TCTI and ESYS are initialized */
97 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
98 TSS2_FAPI_RC_NO_TPM);
99
100 /* If the async state automata of FAPI shall be tested, then we must not set
101 the timeouts of ESYS to blocking mode.
102 During testing, the mssim tcti will ensure multiple re-invocations.
103 Usually however the synchronous invocations of FAPI shall instruct ESYS
104 to block until a result is available. */
105 #ifndef TEST_FAPI_ASYNC
106 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
107 return_if_error_reset_state(r, "Set Timeout to blocking");
108 #endif /* TEST_FAPI_ASYNC */
109
110 r = Fapi_Quote_Async(context, pcrList, pcrListSize, keyPath, quoteType,
111 qualifyingData, qualifyingDataSize);
112 return_if_error_reset_state(r, "PCR_Quote");
113
114 do {
115 /* We wait for file I/O to be ready if the FAPI state automata
116 are in a file I/O state. */
117 r = ifapi_io_poll(&context->io);
118 return_if_error(r, "Something went wrong with IO polling");
119
120 /* Repeatedly call the finish function, until FAPI has transitioned
121 through all execution stages / states of this invocation. */
122 r = Fapi_Quote_Finish(context, quoteInfo, signature, signatureSize,
123 pcrLog, certificate);
124 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
125
126 /* Reset the ESYS timeout to non-blocking, immediate response. */
127 r2 = Esys_SetTimeout(context->esys, 0);
128 return_if_error(r2, "Set Timeout to non-blocking");
129
130 return_if_error_reset_state(r, "PCR_Quote");
131
132 LOG_TRACE("finished");
133 return TSS2_RC_SUCCESS;
134 }
135
136 /** Asynchronous function for Fapi_Quote
137 *
138 * Given a set of PCRs and a restricted signing key, it will sign those PCRs and
139 * return the quote.
140 *
141 * Call Fapi_Quote_Finish to finish the execution of this command.
142 *
143 * @param[in,out] context The FAPI_CONTEXT
144 * @param[in] pcrList The list of PCRs that are to be quoted
145 * @param[in] pcrListSize The size of pcrList in bytes
146 * @param[in] keyPath The path to the signing key
147 * @param[in] quoteType The type of quote. May be NULL
148 * @param[in] qualifyingData A nonce provided by the caller. May be NULL
149 * @param[in] qualifyingDataSize The size of qualifyingData in bytes. Must be 0
150 * if qualifyingData is NULL
151 *
152 * @retval TSS2_RC_SUCCESS: if the function call was a success.
153 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, pcrList or keyPath
154 * is NULL.
155 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
156 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if path does not map to a FAPI entity.
157 * @retval TSS2_FAPI_RC_BAD_KEY: if the entity at path is not a key, or is a key
158 * that is unsuitable for the requested operation.
159 * @retval TSS2_FAPI_RC_BAD_VALUE: if pcrListSize is 0, qualifyingData is
160 * invalid or if qualifyingDataSize is zero.
161 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
162 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
163 * operation already pending.
164 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
165 * internal operations or return parameters.
166 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
167 * config file.
168 */
169 TSS2_RC
170 Fapi_Quote_Async(
171 FAPI_CONTEXT *context,
172 uint32_t *pcrList,
173 size_t pcrListSize,
174 char const *keyPath,
175 char const *quoteType,
176 uint8_t const *qualifyingData,
177 size_t qualifyingDataSize)
178 {
179 LOG_TRACE("called for context:%p", context);
180 LOG_TRACE("pcrListSize: %zi", pcrListSize);
181 for (size_t i = 0; i < pcrListSize; i++) {
182 LOG_TRACE("PCR list entry %zu: %ul", i, pcrList[i]);
183 }
184 LOG_TRACE("keyPath: %s", keyPath);
185 LOG_TRACE("quoteType: %s", quoteType);
186 if (qualifyingData) {
187 LOGBLOB_TRACE(qualifyingData, qualifyingDataSize, "qualifyingData");
188 } else {
189 LOG_TRACE("qualifyingData: (null) qualifyingDataSize: %zi", qualifyingDataSize);
190 }
191
192 TSS2_RC r;
193
194 /* Check for NULL parameters */
195 check_not_null(context);
196 check_not_null(pcrList);
197 check_not_null(keyPath);
198
199 /* Check for invalid parameters */
200 if (pcrListSize == 0) {
201 LOG_ERROR("pcrListSize must not be NULL");
202 return TSS2_FAPI_RC_BAD_VALUE;
203 }
204 if (qualifyingData == NULL && qualifyingDataSize) {
205 LOG_ERROR("QualifyingData is NULL but qualifyingDataSize is not 0");
206 return TSS2_FAPI_RC_BAD_VALUE;
207 }
208
209 /* Helpful alias pointers */
210 IFAPI_PCR * command = &context->cmd.pcr;
211
212 /* Reset all context-internal session state information. */
213 r = ifapi_session_init(context);
214 return_if_error(r, "Initialize Quote");
215
216 if (quoteType && strcmp(quoteType, "TPM-Quote") != 0) {
217 return_error(TSS2_FAPI_RC_BAD_VALUE,
218 "Only quote type TPM-Quote is allowed");
219 }
220
221 /* Store parameters in context */
222 strdup_check(command->keyPath, keyPath, r, error_cleanup);
223
224 command->pcrList = malloc(pcrListSize * sizeof(TPM2_HANDLE));
225 goto_if_null2(command->pcrList, "Out of memory", r, TSS2_FAPI_RC_MEMORY,
226 error_cleanup);
227 memcpy(command->pcrList, pcrList, pcrListSize);
228
229 command->pcrListSize = pcrListSize;
230 command->tpm_quoted = NULL;
231 if (qualifyingData != NULL) {
232 FAPI_COPY_DIGEST(&command->qualifyingData.buffer[0],
233 command->qualifyingData.size, qualifyingData, qualifyingDataSize);
234 } else {
235 command->qualifyingData.size = 0;
236 }
237
238 /* Initialize the context state for this operation. */
239 context->state = PCR_QUOTE_WAIT_FOR_GET_CAP;
240 LOG_TRACE("finished");
241 return TSS2_RC_SUCCESS;
242
243 error_cleanup:
244 /* Cleanup duplicated input parameters that were copied before. */
245 SAFE_FREE(command->keyPath);
246 SAFE_FREE(command->pcrList);
247 return r;
248 }
249
250 /** Asynchronous finish function for Fapi_Quote
251 *
252 * This function should be called after a previous Fapi_Quote_Async.
253 *
254 * @param[in,out] context The FAPI_CONTEXT
255 * @param[out] quoteInfo A JSON-encoded structure holding the inputs to the
256 * quote operation
257 * @param[out] signature The signature of the PCRs
258 * @param[out] signatureSize The size of the signature in bytes. May be NULL
259 * @param[out] pcrLog The log of the PCR. May be NULL
260 * @param[out] certificate The certificate associated with the signing key. May
261 * be NULL
262 *
263 * @retval TSS2_RC_SUCCESS: if the function call was a success.
264 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, quoteInfor or signature
265 * is NULL.
266 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
267 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
268 * operation already pending.
269 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
270 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
271 * internal operations or return parameters.
272 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
273 * complete. Call this function again later.
274 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
275 * the function.
276 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
277 * during authorization.
278 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
279 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
280 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
281 * is not set.
282 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
283 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
284 * was not successful.
285 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
286 */
287 TSS2_RC
288 Fapi_Quote_Finish(
289 FAPI_CONTEXT *context,
290 char **quoteInfo,
291 uint8_t **signature,
292 size_t *signatureSize,
293 char **pcrLog,
294 char **certificate)
295 {
296 LOG_TRACE("called for context:%p", context);
297
298 TSS2_RC r;
299 IFAPI_OBJECT *sig_key_object;
300 const IFAPI_PROFILE *profile;
301 ESYS_TR auth_session;
302
303 /* Check for NULL parameters */
304 check_not_null(context);
305 check_not_null(quoteInfo);
306 check_not_null(signature);
307
308 /* Helpful alias pointers */
309 IFAPI_PCR * command = &context->cmd.pcr;
310
311 switch (context->state) {
312 statecase(context->state, PCR_QUOTE_WAIT_FOR_GET_CAP);
313 command->pcr_selection = context->profiles.default_profile.pcr_selection;
314
315 r = ifapi_filter_pcr_selection_by_index(&command->pcr_selection,
316 command->pcrList,
317 command->pcrListSize);
318 goto_if_error_reset_state(r, "Filtering banks for PCR list.", error_cleanup);
319
320 /* Get a session for authorization of the quote operation. */
321 r = ifapi_get_sessions_async(context,
322 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
323 TPMA_SESSION_DECRYPT, 0);
324 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
325
326 fallthrough;
327
328 statecase(context->state, PCR_QUOTE_WAIT_FOR_SESSION);
329 /* Retrieve the profile information. */
330 r = ifapi_profiles_get(&context->profiles, command->keyPath, &profile);
331 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
332
333 r = ifapi_get_sessions_finish(context, profile, profile->nameAlg);
334 return_try_again(r);
335 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
336
337 /* Load the key into the TPM. */
338 r = ifapi_load_keys_async(context, command->keyPath);
339 goto_if_error(r, "Load keys.", error_cleanup);
340
341 fallthrough;
342
343 statecase(context->state, PCR_QUOTE_WAIT_FOR_KEY);
344 r = ifapi_load_keys_finish(context, IFAPI_FLUSH_PARENT,
345 &command->handle,
346 &command->key_object);
347 return_try_again(r);
348 goto_if_error_reset_state(r, " Load key.", error_cleanup);
349
350 fallthrough;
351
352 statecase(context->state, PCR_QUOTE_AUTHORIZE);
353 /* Authorize the session for use with the key. */
354 r = ifapi_authorize_object(context, command->key_object, &auth_session);
355 return_try_again(r);
356 goto_if_error(r, "Authorize key.", error_cleanup);
357
358 /* Perform the Quote operation. */
359 r = Esys_Quote_Async(context->esys, command->handle,
360 auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
361 &command->qualifyingData,
362 &command->key_object->misc.key.signing_scheme,
363 &command->pcr_selection);
364 goto_if_error(r, "Error: PCR_Quote", error_cleanup);
365
366 fallthrough;
367
368 statecase(context->state, PCR_QUOTE_AUTH_SENT);
369 command->tpm_signature = NULL;
370 SAFE_FREE(command->tpm_signature);
371 r = Esys_Quote_Finish(context->esys, &command->tpm_quoted,
372 &command->tpm_signature);
373 return_try_again(r);
374 goto_if_error(r, "Error: PCR_Quote", error_cleanup);
375
376 /* Flush the key used for the quote. */
377 r = Esys_FlushContext_Async(context->esys, command->handle);
378 goto_if_error(r, "Error: FlushContext", error_cleanup);
379
380 fallthrough;
381
382 statecase(context->state, PCR_QUOTE_WAIT_FOR_FLUSH);
383 r = Esys_FlushContext_Finish(context->esys);
384 return_try_again(r);
385 goto_if_error(r, "Error: Sign", error_cleanup);
386
387 sig_key_object = command->key_object;
388 /* Convert the TPM-encoded signature into something useful for the caller. */
389 r = ifapi_tpm_to_fapi_signature(sig_key_object,
390 command->tpm_signature,
391 signature, signatureSize);
392 SAFE_FREE(command->tpm_signature);
393 goto_if_error(r, "Create FAPI signature.", error_cleanup);
394
395 /* Compute the quote info; i.e. the data that was actually
396 signed by the TPM. */
397 r = ifapi_compute_quote_info(sig_key_object,
398 command->tpm_quoted,
399 quoteInfo);
400 goto_if_error(r, "Create compute quote info.", error_cleanup);
401
402 /* Return the key's certificate if requested. */
403 if (certificate) {
404 strdup_check(*certificate, sig_key_object->misc.key.certificate, r, error_cleanup);
405 }
406
407 /* If the pcrLog was not requested, the operation is done. */
408 if (!pcrLog) {
409 context->state = PCR_QUOTE_CLEANUP;
410 return TSS2_FAPI_RC_TRY_AGAIN;
411 }
412
413 /* Retrieve the eventlog for the PCRs for the quote. */
414 r = ifapi_eventlog_get_async(&context->eventlog, &context->io,
415 command->pcrList,
416 command->pcrListSize);
417 goto_if_error(r, "Error getting event log", error_cleanup);
418
419 fallthrough;
420
421 statecase(context->state, PCR_QUOTE_READ_EVENT_LIST);
422 r = ifapi_eventlog_get_finish(&context->eventlog, &context->io, pcrLog);
423 return_try_again(r);
424 goto_if_error(r, "Error getting event log", error_cleanup);
425 fallthrough;
426
427 statecase(context->state, PCR_QUOTE_CLEANUP)
428 /* Cleanup the session used for authorization. */
429 r = ifapi_cleanup_session(context);
430 try_again_or_error_goto(r, "Cleanup", error_cleanup);
431
432 context->state = _FAPI_STATE_INIT;
433 break;
434
435 statecasedefault(context->state);
436 }
437
438 error_cleanup:
439 /* Cleanup any intermediate results and state stored in the context. */
440 SAFE_FREE(command->tpm_signature);
441 SAFE_FREE(command->tpm_quoted);
442 SAFE_FREE(command->keyPath);
443 SAFE_FREE(command->pcrList);
444 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
445 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
446 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
447 ifapi_cleanup_ifapi_object(command->key_object);
448 ifapi_session_clean(context);
449 LOG_TRACE("finished");
450 return r;
451 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 /** One-Call function for Fapi_SetAppData
25 *
26 * Associates an arbitrary data blob with a given object.
27 *
28 * @param[in,out] context The FAPI_CONTEXT
29 * @param[in] path The path to the object the blob is associated with
30 * @param[in] appData The blob to associate with the object. May be NULL
31 * @param[in] appDataSize The size of appData in bytes. Must be 0 if appData is
32 * NULL
33 *
34 * @retval TSS2_RC_SUCCESS: if the function call was a success.
35 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL or if appData
36 * is NULL and appDataSize is not 0.
37 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
38 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
39 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
40 * operation already pending.
41 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
42 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
43 * internal operations or return parameters.
44 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
45 * the function.
46 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
47 * during authorization.
48 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
49 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
50 * this function needs to be called again.
51 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
52 */
53 TSS2_RC
54 Fapi_SetAppData(
55 FAPI_CONTEXT *context,
56 char const *path,
57 uint8_t const *appData,
58 size_t appDataSize)
59 {
60 LOG_TRACE("called for context:%p", context);
61
62 TSS2_RC r;
63
64 /* Check for NULL parameters */
65 check_not_null(context);
66 check_not_null(path);
67
68 r = Fapi_SetAppData_Async(context, path, appData, appDataSize);
69 return_if_error_reset_state(r, "SetAppData");
70
71 do {
72 /* We wait for file I/O to be ready if the FAPI state automata
73 are in a file I/O state. */
74 r = ifapi_io_poll(&context->io);
75 return_if_error(r, "Something went wrong with IO polling");
76
77 /* Repeatedly call the finish function, until FAPI has transitioned
78 through all execution stages / states of this invocation. */
79 r = Fapi_SetAppData_Finish(context);
80 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
81
82 return_if_error_reset_state(r, "SetAppData");
83
84 LOG_TRACE("finished");
85 return TSS2_RC_SUCCESS;
86 }
87
88 /** One-Call function for Fapi_SetAppData
89 *
90 * Associates an arbitrary data blob with a given object.
91 *
92 * Call Fapi_SetAppData_Finish to finish the execution of this command.
93 *
94 * @param[in,out] context The FAPI_CONTEXT
95 * @param[in] path The path to the object the blob is associated with
96 * @param[in] appData The blob to associate with the object. May be NULL
97 * @param[in] appDataSize The size of appData in bytes. Must be 0 if appData is
98 * NULL
99 *
100 * @retval TSS2_RC_SUCCESS: if the function call was a success.
101 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL or if appData
102 * is NULL and appDataSize is not 0.
103 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
104 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
105 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
106 * operation already pending.
107 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
108 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
109 * internal operations or return parameters.
110 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
111 * the function.
112 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
113 * during authorization.
114 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
115 */
116 TSS2_RC
117 Fapi_SetAppData_Async(
118 FAPI_CONTEXT *context,
119 char const *path,
120 uint8_t const *appData,
121 size_t appDataSize)
122 {
123 LOG_TRACE("called for context:%p", context);
124 LOG_TRACE("path: %s", path);
125 if (appData) {
126 LOGBLOB_TRACE(appData, appDataSize, "appData");
127 } else {
128 LOG_TRACE("appData: (null) appDataSize: %zi", appDataSize);
129 }
130
131 TSS2_RC r;
132
133 /* Check for NULL parameters */
134 check_not_null(context);
135 check_not_null(path);
136
137 /* Check for invalid parameters */
138 if (!appData && appDataSize != 0) {
139 return_error(TSS2_FAPI_RC_BAD_VALUE,
140 "NULL-pointer passed for appData, though appDataSize != 0.");
141 }
142
143 /* Helpful alias pointers */
144 IFAPI_Path_SetDescription * command = &context->cmd.path_set_info;
145
146 /* Copy parameters to context for use during _Finish. */
147 strdup_check(command->object_path, path, r, error_cleanup);
148
149 if (appDataSize > 0) {
150 command->appData.buffer = malloc(appDataSize);
151 goto_if_null2(command->appData.buffer, "Out of memory.",
152 r, TSS2_FAPI_RC_MEMORY, error_cleanup);
153
154 memcpy(&command->appData.buffer[0], appData, appDataSize);
155 } else {
156 command->appData.buffer = NULL;
157 }
158 command->appData.size = appDataSize;
159
160 /* Load the current metadata for the object from keystore. */
161 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
162 return_if_error2(r, "Could not open: %s", path);
163
164 /* Initialize the context state for this operation. */
165 context->state = APP_DATA_SET_READ;
166 LOG_TRACE("finished");
167 return TSS2_RC_SUCCESS;
168
169 error_cleanup:
170 /* Cleanup duplicated input parameters that were copied before. */
171 SAFE_FREE(command->object_path);
172 SAFE_FREE(command->appData.buffer);
173 return r;
174 }
175
176 /** Asynchronous finish function for Fapi_SetAppData
177 *
178 * This function should be called after a previous Fapi_SetAppData_Async.
179 *
180 * @param[in,out] context The FAPI_CONTEXT
181 *
182 * @retval TSS2_RC_SUCCESS: if the function call was a success.
183 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
184 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
185 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
186 * operation already pending.
187 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
188 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
189 * internal operations or return parameters.
190 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
191 * complete. Call this function again later.
192 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
193 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
194 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
195 * the function.
196 */
197 TSS2_RC
198 Fapi_SetAppData_Finish(
199 FAPI_CONTEXT *context)
200 {
201 LOG_TRACE("called for context:%p", context);
202
203 TSS2_RC r;
204
205 /* Check for NULL parameters */
206 check_not_null(context);
207
208 /* Helpful alias pointers */
209 IFAPI_Path_SetDescription * command = &context->cmd.path_set_info;
210 IFAPI_OBJECT *object = &command->object;
211 UINT8_ARY *objAppData;
212
213 switch (context->state) {
214 statecase(context->state, APP_DATA_SET_READ);
215 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
216 return_try_again(r);
217 return_if_error_reset_state(r, "read_finish failed");
218
219 /* Depending on the object type get the correct appData pointer. */
220 switch (object->objectType) {
221 case IFAPI_KEY_OBJ:
222 objAppData = &object->misc.key.appData;
223 break;
224 case IFAPI_NV_OBJ:
225 objAppData = &object->misc.nv.appData;
226 break;
227 default:
228 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "Object has no app data.", error_cleanup);
229 }
230
231 /* If exists delete old appData */
232 SAFE_FREE(objAppData->buffer);
233
234 /* Set new appData for object */
235 objAppData->size = command->appData.size;
236 objAppData->buffer = command->appData.buffer;
237
238 /* Prepare (over-)writing of object */
239 r = ifapi_keystore_store_async(&context->keystore, &context->io,
240 command->object_path, object);
241 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
242 command->object_path);
243
244 fallthrough;
245
246 statecase(context->state, APP_DATA_SET_WRITE);
247 /* Finish writing of object */
248 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
249 return_try_again(r);
250 return_if_error_reset_state(r, "write_finish failed");
251 ifapi_cleanup_ifapi_object(object);
252
253 context->state = _FAPI_STATE_INIT;
254 r = TSS2_RC_SUCCESS;
255 break;
256
257 statecasedefault(context->state);
258 }
259
260 error_cleanup:
261 /* Cleanup any intermediate results and state stored in the context. */
262 ifapi_cleanup_ifapi_object(object);
263 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
264 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
265 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
266 SAFE_FREE(command->object_path);
267 LOG_TRACE("finished");
268 return r;
269 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16
17 #include "tss2_fapi.h"
18 #include "fapi_int.h"
19 #include "fapi_util.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24 #include "fapi_crypto.h"
25
26 /** One-Call function for Fapi_SetCertificate
27 *
28 * Sets an x509 cert into the path of a key.
29 *
30 * @param[in,out] context The FAPI_CONTEXT
31 * @param[in] path The path of the entity to be associated with the
32 * certificate
33 * @param[in] x509certData The certificate that is associated with the entity.
34 * If this is NULL an existing certificate will be removed from
35 * the entity
36 *
37 * @retval TSS2_RC_SUCCESS: if the function call was a success.
38 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
39 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
40 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if path does not map to a FAPI entity.
41 * @retval TSS2_FAPI_RC_BAD_KEY: if x509certData is invalid.
42 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
43 * operation already pending.
44 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
45 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
46 * internal operations or return parameters.
47 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
48 * during authorization.
49 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
50 * the function.
51 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
52 * this function needs to be called again.
53 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
54 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
55 */
56 TSS2_RC
57 Fapi_SetCertificate(
58 FAPI_CONTEXT *context,
59 char const *path,
60 char const *x509certData)
61 {
62 LOG_TRACE("called for context:%p", context);
63
64 TSS2_RC r;
65
66 /* Check for NULL parameters */
67 check_not_null(context);
68 check_not_null(path);
69
70 r = Fapi_SetCertificate_Async(context, path, x509certData);
71 return_if_error_reset_state(r, "Key_SetCertificate");
72
73 do {
74 /* We wait for file I/O to be ready if the FAPI state automata
75 are in a file I/O state. */
76 r = ifapi_io_poll(&context->io);
77 return_if_error(r, "Something went wrong with IO polling");
78
79 /* Repeatedly call the finish function, until FAPI has transitioned
80 through all execution stages / states of this invocation. */
81 r = Fapi_SetCertificate_Finish(context);
82 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
83
84 return_if_error_reset_state(r, "Key_SetCertificate");
85
86 LOG_TRACE("finished");
87 return TSS2_RC_SUCCESS;
88 }
89
90 /** Asynchronous function for Fapi_SetCertificate
91 *
92 * Sets an x509 cert into the path of a key.
93 *
94 * Call Fapi_SetCertificate_Finish to finish the execution of this command.
95 *
96 * @param[in,out] context The FAPI_CONTEXT
97 * @param[in] path The path of the entity to be associated with the
98 * certificate
99 * @param[in] x509certData The certificate that is associated with the entity.
100 * If this is NULL an existing certificate will be removed from
101 * the entity
102 *
103 * @retval TSS2_RC_SUCCESS: if the function call was a success.
104 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
105 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
106 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if path does not map to a FAPI entity.
107 * @retval TSS2_FAPI_RC_BAD_KEY: if x509certData is invalid.
108 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
109 * operation already pending.
110 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
111 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
112 * internal operations or return parameters.
113 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
114 * during authorization.
115 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
116 * the function.
117 */
118 TSS2_RC
119 Fapi_SetCertificate_Async(
120 FAPI_CONTEXT *context,
121 char const *path,
122 char const *x509certData)
123 {
124 LOG_TRACE("called for context:%p", context);
125 LOG_TRACE("path: %s", path);
126 LOG_TRACE("x509certData: %s", x509certData);
127
128 TSS2_RC r;
129
130 /* Check for NULL parameters */
131 check_not_null(context);
132 check_not_null(path);
133
134 /* Helpful alias pointers */
135 IFAPI_Key_SetCertificate * command = &context->cmd.Key_SetCertificate;
136
137 r = ifapi_non_tpm_mode_init(context);
138 goto_if_error(r, "Initialize SetCertificate", error_cleanup);
139
140 /* Copy parameters to context for use during _Finish. */
141 if (x509certData) {
142 strdup_check(command->pem_cert, x509certData, r, error_cleanup);
143 } else {
144 command->pem_cert = NULL;
145 }
146 strdup_check(command->key_path, path, r, error_cleanup);
147 context->state = KEY_SET_CERTIFICATE_READ;
148 memset(&command->key_object, 0, sizeof(IFAPI_OBJECT));
149
150 /* Load the object's current metadata from the keystore. */
151 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
152 goto_if_error2(r, "Could not open: %s", error_cleanup, path);
153
154 LOG_TRACE("finished");
155 return TSS2_RC_SUCCESS;
156
157 error_cleanup:
158 /* Initialize the context state for this operation. */
159 SAFE_FREE(command->pem_cert);
160 SAFE_FREE(command->key_path);
161 return r;
162 }
163
164 /** Asynchronous finish function for Fapi_SetCertificate
165 *
166 * This function should be called after a previous Fapi_SetCertificate_Async.
167 *
168 * @param[in,out] context The FAPI_CONTEXT
169 *
170 * @retval TSS2_RC_SUCCESS: if the function call was a success.
171 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
172 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
173 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
174 * operation already pending.
175 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
176 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
177 * internal operations or return parameters.
178 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
179 * complete. Call this function again later.
180 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
181 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
182 * the function.
183 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
184 */
185 TSS2_RC
186 Fapi_SetCertificate_Finish(
187 FAPI_CONTEXT *context)
188 {
189 LOG_TRACE("called for context:%p", context);
190
191 TSS2_RC r;
192
193 /* Check for NULL parameters */
194 check_not_null(context);
195
196 /* Helpful alias pointers */
197 IFAPI_Key_SetCertificate * command = &context->cmd.Key_SetCertificate;
198 IFAPI_OBJECT *key_object = &command->key_object;
199 const char ** pem_cert = &command->pem_cert;
200 char ** pem_cert_dup = &command->pem_cert_dup;
201
202 switch (context->state) {
203 statecase(context->state, KEY_SET_CERTIFICATE_READ)
204 r = ifapi_keystore_load_finish(&context->keystore, &context->io, key_object);
205 return_try_again(r);
206 return_if_error_reset_state(r, "read_finish failed");
207
208 /* Duplicate and store the certificate in the key object. */
209 if (!*pem_cert) {
210 strdup_check(*pem_cert_dup, "", r, error_cleanup);
211 } else {
212 strdup_check(*pem_cert_dup, *pem_cert, r, error_cleanup);
213 }
214 if (key_object->objectType == IFAPI_EXT_PUB_KEY_OBJ) {
215 SAFE_FREE(key_object->misc.ext_pub_key.certificate);
216 key_object->misc.ext_pub_key.certificate = *pem_cert_dup;
217 } else {
218 SAFE_FREE(key_object->misc.key.certificate);
219 key_object->misc.key.certificate = *pem_cert_dup;
220 }
221
222 /* Perform esys serialization if necessary */
223 r = ifapi_esys_serialize_object(context->esys, key_object);
224 goto_if_error(r, "Prepare serialization", error_cleanup);
225
226 /* Start writing the NV object to the key store */
227 r = ifapi_keystore_store_async(&context->keystore, &context->io,
228 command->key_path, key_object);
229 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
230 command->key_path);
231
232 context->state = KEY_SET_CERTIFICATE_WRITE;
233 fallthrough;
234
235 statecase(context->state, KEY_SET_CERTIFICATE_WRITE)
236 /* Finish writing the object to the key store */
237 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
238 return_try_again(r);
239 return_if_error_reset_state(r, "write_finish failed");
240
241 context->state = _FAPI_STATE_INIT;
242 r = TSS2_RC_SUCCESS;
243 break;
244
245 statecasedefault(context->state);
246 }
247
248 error_cleanup:
249 /* Cleanup any intermediate results and state stored in the context. */
250 SAFE_FREE(command->pem_cert);
251 SAFE_FREE(command->key_path);
252 if (key_object->objectType) {
253 ifapi_cleanup_ifapi_object(key_object);
254 }
255 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
256 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
257 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
258 LOG_TRACE("finished");
259 return r;
260 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 /** One-Call function for Fapi_SetDescription
25 *
26 * Associates a human readable description with an object in the metadata store.
27 *
28 * @param[in,out] context The FAPI_CONTEXT
29 * @param[in] path The path of the object in the metadata store
30 * @param[in] description The description that is associated with the object.
31 * May be NULL
32 *
33 * @retval TSS2_RC_SUCCESS: if the function call was a success.
34 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
35 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
36 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
37 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
38 * operation already pending.
39 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
40 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
41 * internal operations or return parameters.
42 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
43 * the function.
44 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
45 * during authorization.
46 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
47 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
48 * this function needs to be called again.
49 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
50 */
51 TSS2_RC
52 Fapi_SetDescription(
53 FAPI_CONTEXT *context,
54 char const *path,
55 char const *description)
56 {
57 LOG_TRACE("called for context:%p", context);
58
59 TSS2_RC r;
60
61 /* Check for NULL parameters */
62 check_not_null(context);
63 check_not_null(path);
64
65 r = Fapi_SetDescription_Async(context, path, description);
66 return_if_error_reset_state(r, "Path_SetDescription");
67
68 do {
69 /* We wait for file I/O to be ready if the FAPI state automata
70 are in a file I/O state. */
71 r = ifapi_io_poll(&context->io);
72 return_if_error(r, "Something went wrong with IO polling");
73
74 /* Repeatedly call the finish function, until FAPI has transitioned
75 through all execution stages / states of this invocation. */
76 r = Fapi_SetDescription_Finish(context);
77 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
78
79 return_if_error_reset_state(r, "Path_SetDescription");
80
81 LOG_TRACE("finished");
82 return TSS2_RC_SUCCESS;
83 }
84
85 /** Asynchronous function for Fapi_SetDescription
86 *
87 * Associates a human readable description with an object in the metadata store.
88 *
89 * Call Fapi_SetDescription_Finish to finish the execution of this command.
90 *
91 * @param[in,out] context The FAPI_CONTEXT
92 * @param[in] path The path of the object in the metadata store
93 * @param[in] description The description that is associated with the object.
94 * May be NULL
95 *
96 * @retval TSS2_RC_SUCCESS: if the function call was a success.
97 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
98 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
99 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI entity.
100 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
101 * operation already pending.
102 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
103 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
104 * internal operations or return parameters.
105 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
106 * the function.
107 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
108 * during authorization.
109 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
110 */
111 TSS2_RC
112 Fapi_SetDescription_Async(
113 FAPI_CONTEXT *context,
114 char const *path,
115 char const *description)
116 {
117 LOG_TRACE("called for context:%p", context);
118 LOG_TRACE("path: %s", path);
119 LOG_TRACE("description: %s", description);
120
121 TSS2_RC r;
122
123 /* Check for NULL parameters */
124 check_not_null(context);
125 check_not_null(path);
126
127 /* Check for invalid parameters */
128 if (description && strlen(description) + 1 > 1024) {
129 return_error(TSS2_FAPI_RC_BAD_VALUE,
130 "Length of description > 1024");
131 }
132
133 /* Helpful alias pointers */
134 IFAPI_Path_SetDescription * command = &context->cmd.path_set_info;
135
136 /* Copy parameters to context for use during _Finish. */
137 strdup_check(command->object_path, path, r, error_cleanup);
138
139 /* Load the object's current metadata from the keystore. */
140 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
141 goto_if_error2(r, "Could not open: %s", error_cleanup, path);
142
143 if (description == NULL) {
144 command->description = NULL;
145 } else {
146 strdup_check(command->description, description, r, error_cleanup);
147 }
148
149
150 /* Initialize the context state for this operation. */
151 context->state = PATH_SET_DESCRIPTION_READ;
152 LOG_TRACE("finished");
153 return TSS2_RC_SUCCESS;
154
155 error_cleanup:
156 /* Cleanup duplicated input parameters that were copied before. */
157 SAFE_FREE(command->object_path);
158 SAFE_FREE(command->description);
159 return r;
160 }
161
162 /** Asynchronous finish function for Fapi_SetDescription
163 *
164 * This function should be called after a previous Fapi_SetDescription_Async.
165 *
166 * @param[in,out] context The FAPI_CONTEXT
167 *
168 * @retval TSS2_RC_SUCCESS: if the function call was a success.
169 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
170 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
171 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
172 * operation already pending.
173 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
174 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
175 * internal operations or return parameters.
176 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If no file is found after pathname expansion.
177 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
178 * complete. Call this function again later.
179 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
180 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
181 * the function.
182 */
183 TSS2_RC
184 Fapi_SetDescription_Finish(
185 FAPI_CONTEXT *context)
186 {
187 LOG_TRACE("called for context:%p", context);
188
189 TSS2_RC r;
190
191 /* Check for NULL parameters */
192 check_not_null(context);
193
194 /* Helpful alias pointers */
195 IFAPI_Path_SetDescription * command = &context->cmd.path_set_info;
196 IFAPI_OBJECT *object = &command->object;
197
198 switch (context->state) {
199 statecase(context->state, PATH_SET_DESCRIPTION_READ);
200 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
201 return_try_again(r);
202 goto_if_error_reset_state(r, "read_finish failed", error_cleanup);
203
204 /* Add new description to object and save object */
205 ifapi_set_description(object, command->description);
206
207 /* Store the updated metadata back to the keystore. */
208 r = ifapi_keystore_store_async(&context->keystore, &context->io,
209 command->object_path, object);
210 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
211 command->object_path);
212
213 fallthrough;
214
215 statecase(context->state, PATH_SET_DESCRIPTION_WRITE);
216 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
217 return_try_again(r);
218 return_if_error_reset_state(r, "write_finish failed");
219
220 context->state = _FAPI_STATE_INIT;
221 r = TSS2_RC_SUCCESS;
222 break;
223
224 statecasedefault(context->state);
225 }
226
227 error_cleanup:
228 /* Cleanup any intermediate results and state stored in the context. */
229 ifapi_cleanup_ifapi_object(object);
230 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
231 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
232 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
233 SAFE_FREE(command->object_path);
234 LOG_TRACE("finished");
235 return r;
236 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "fapi_policy.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24 #include "fapi_crypto.h"
25
26 /** One-Call function for Fapi_Sign
27 *
28 * Uses a key, identified by its path, to sign a digest and puts the result in a
29 * TPM2B bytestream.
30 *
31 * @param[in,out] context The FAPI_CONTEXT
32 * @param[in] keyPath The path of the signature key
33 * @param[in] padding A padding algorithm. Must be either "RSA_SSA" or
34 * "RSA_PSS" or NULL
35 * @param[in] digest The digest to sign. Must be already hashed
36 * @param[in] digestSize The size of the digest in bytes
37 * @param[out] signature The signature
38 * @param[out] signatureSize The size of signature in bytes. May be NULL
39 * @param[out] publicKey The public key that can be used to verify signature
40 * in PEM format. May be NULL
41 * @param[out] certificate The certificate associated with the signing key in PEM
42 * format. May be NULL
43 *
44 * @retval TSS2_RC_SUCCESS: if the function call was a success.
45 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, keyPath, digest or signature
46 * is NULL.
47 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
48 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if keyPath does not map to a FAPI key.
49 * @retval TSS2_FAPI_RC_BAD_KEY: if the object at keyPath is not a key, or is a
50 * key that is unsuitable for the requested operation.
51 * @retval TSS2_FAPI_RC_BAD_VALUE: if the digestSize is zero.
52 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
53 * operation already pending.
54 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
55 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
56 * internal operations or return parameters.
57 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
58 * config file.
59 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
60 * this function needs to be called again.
61 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
62 * during authorization.
63 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
64 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
65 * is not set.
66 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
67 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
68 * was not successful.
69 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
70 */
71 TSS2_RC
72 Fapi_Sign(
73 FAPI_CONTEXT *context,
74 char const *keyPath,
75 char const *padding,
76 uint8_t const *digest,
77 size_t digestSize,
78 uint8_t **signature,
79 size_t *signatureSize,
80 char **publicKey,
81 char **certificate)
82 {
83 LOG_TRACE("called for context:%p", context);
84
85 TSS2_RC r, r2;
86
87 /* Check for NULL parameters */
88 check_not_null(context);
89 check_not_null(keyPath);
90 check_not_null(digest);
91 check_not_null(signature);
92
93 /* Check whether TCTI and ESYS are initialized */
94 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
95 TSS2_FAPI_RC_NO_TPM);
96
97 /* If the async state automata of FAPI shall be tested, then we must not set
98 the timeouts of ESYS to blocking mode.
99 During testing, the mssim tcti will ensure multiple re-invocations.
100 Usually however the synchronous invocations of FAPI shall instruct ESYS
101 to block until a result is available. */
102 #ifndef TEST_FAPI_ASYNC
103 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
104 return_if_error_reset_state(r, "Set Timeout to blocking");
105 #endif /* TEST_FAPI_ASYNC */
106
107 r = Fapi_Sign_Async(context, keyPath, padding, digest, digestSize);
108 return_if_error_reset_state(r, "Key_Sign");
109
110 do {
111 /* We wait for file I/O to be ready if the FAPI state automata
112 are in a file I/O state. */
113 r = ifapi_io_poll(&context->io);
114 return_if_error(r, "Something went wrong with IO polling");
115
116 /* Repeatedly call the finish function, until FAPI has transitioned
117 through all execution stages / states of this invocation. */
118 r = Fapi_Sign_Finish(context, signature, signatureSize, publicKey,
119 certificate);
120 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
121
122 /* Reset the ESYS timeout to non-blocking, immediate response. */
123 r2 = Esys_SetTimeout(context->esys, 0);
124 return_if_error(r2, "Set Timeout to non-blocking");
125
126 return_if_error_reset_state(r, "Key_Sign");
127
128 LOG_TRACE("finished");
129 return TSS2_RC_SUCCESS;
130 }
131
132 /** Asynchronous function for Fapi_Sign
133 *
134 * Uses a key, identified by its path, to sign a digest and puts the result in a
135 * TPM2B bytestream.
136 *
137 * Call Fapi_Sign_Finish to finish the execution of this command.
138 *
139 * @param[in,out] context The FAPI_CONTEXT
140 * @param[in] keyPath The path of the signature key
141 * @param[in] padding A padding algorithm. Must be either "RSA_SSA" or
142 * "RSA_PSS" or NULL
143 * @param[in] digest The digest to sign. Must be already hashed
144 * @param[in] digestSize The size of the digest in bytes
145 *
146 * @retval TSS2_RC_SUCCESS: if the function call was a success.
147 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, keyPath or digest
148 * is NULL.
149 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
150 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if keyPath does not map to a FAPI key.
151 * @retval TSS2_FAPI_RC_BAD_KEY: if the object at keyPath is not a key, or is a
152 * key that is unsuitable for the requested operation.
153 * @retval TSS2_FAPI_RC_BAD_VALUE: if the digestSize is zero.
154 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
155 * operation already pending.
156 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
157 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
158 * internal operations or return parameters.
159 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
160 * config file.
161 */
162 TSS2_RC
163 Fapi_Sign_Async(
164 FAPI_CONTEXT *context,
165 char const *keyPath,
166 char const *padding,
167 uint8_t const *digest,
168 size_t digestSize)
169 {
170 LOG_TRACE("called for context:%p", context);
171 LOG_TRACE("keyPath: %s", keyPath);
172 LOG_TRACE("padding: %s", padding);
173 if (digest) {
174 LOGBLOB_TRACE(digest, digestSize, "digest");
175 } else {
176 LOG_TRACE("digest: (null) digestSize: %zi", digestSize);
177 }
178
179 TSS2_RC r;
180
181 /* Check for NULL parameters */
182 check_not_null(context);
183 check_not_null(keyPath);
184 check_not_null(digest);
185
186 /* Check for invalid parameters */
187 if (padding) {
188 if (strcasecmp("RSA_SSA", padding) != 0 &&
189 strcasecmp("RSA_PSS", padding) != 0) {
190 return_error(TSS2_FAPI_RC_BAD_VALUE,
191 "Only padding RSA_SSA or RSA_PSS allowed.");
192 }
193 }
194
195 /* Helpful alias pointers */
196 IFAPI_Key_Sign * command = &context->Key_Sign;
197
198 /* Reset all context-internal session state information. */
199 r = ifapi_session_init(context);
200 return_if_error(r, "Initialize Sign");
201
202 /* Copy parameters to context for use during _Finish. */
203 FAPI_COPY_DIGEST(&command->digest.buffer[0],
204 command->digest.size, digest, digestSize);
205 strdup_check(command->keyPath, keyPath, r, error_cleanup);
206 strdup_check(command->padding, padding, r, error_cleanup);
207
208 /* Initialize the context state for this operation. */
209 context->state = KEY_SIGN_WAIT_FOR_KEY;
210 LOG_TRACE("finished");
211 return TSS2_RC_SUCCESS;
212
213 error_cleanup:
214 /* Cleanup duplicated input parameters that were copied before. */
215 SAFE_FREE(command->keyPath);
216 SAFE_FREE(command->padding);
217 return r;
218 }
219
220 /** Asynchronous finish function for Fapi_Sign
221 *
222 * This function should be called after a previous Fapi_Sign_Async.
223 *
224 * @param[in,out] context The FAPI_CONTEXT
225 * @param[out] signature The signature
226 * @param[out] signatureSize The size of signature in bytes. May be NULL
227 * @param[out] publicKey The public key that can be used to verify signature
228 * in PEM format. May be NULL
229 * @param[out] certificate The certificate associated with the signing key in PEM
230 * format. May be NULL
231 *
232 * @retval TSS2_RC_SUCCESS: if the function call was a success.
233 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or signature is NULL.
234 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
235 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
236 * operation already pending.
237 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
238 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
239 * internal operations or return parameters.
240 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
241 * complete. Call this function again later.
242 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
243 * during authorization.
244 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
245 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
246 * the function.
247 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
248 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
249 * is not set.
250 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
251 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
252 * was not successful.
253 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
254 */
255 TSS2_RC
256 Fapi_Sign_Finish(
257 FAPI_CONTEXT *context,
258 uint8_t **signature,
259 size_t *signatureSize,
260 char **publicKey,
261 char **certificate)
262 {
263 LOG_TRACE("called for context:%p", context);
264
265 TSS2_RC r;
266 size_t resultSignatureSize;
267
268 /* Check for NULL parameters */
269 check_not_null(context);
270 check_not_null(signature);
271
272 /* Helpful alias pointers */
273 IFAPI_Key_Sign * command = &context->Key_Sign;
274
275 switch (context->state) {
276 statecase(context->state, KEY_SIGN_WAIT_FOR_KEY);
277 /* Load the key used for signing with a helper. */
278 r = ifapi_load_key(context, command->keyPath,
279 &command->key_object);
280 return_try_again(r);
281 goto_if_error(r, "Fapi load key.", error_cleanup);
282
283 fallthrough;
284
285 statecase(context->state, KEY_SIGN_WAIT_FOR_SIGN);
286 /* Perform the signing operation using a helper. */
287 r = ifapi_key_sign(context, command->key_object,
288 command->padding, &command->digest, &command->tpm_signature,
289 publicKey, certificate);
290 return_try_again(r);
291 goto_if_error(r, "Fapi sign.", error_cleanup);
292
293 /* Convert the TPM datatype signature to something useful for the caller. */
294 r = ifapi_tpm_to_fapi_signature(command->key_object,
295 command->tpm_signature, signature, &resultSignatureSize);
296 goto_if_error(r, "Create FAPI signature.", error_cleanup);
297
298 if (signatureSize)
299 *signatureSize = resultSignatureSize;
300 fallthrough;
301
302 statecase(context->state, KEY_SIGN_CLEANUP)
303 /* Cleanup the session used for authorization. */
304 r = ifapi_cleanup_session(context);
305 try_again_or_error_goto(r, "Cleanup", error_cleanup);
306
307 context->state = _FAPI_STATE_INIT;
308 break;
309
310 statecasedefault(context->state);
311 }
312
313 error_cleanup:
314 /* Cleanup any intermediate results and state stored in the context. */
315 SAFE_FREE(command->tpm_signature);
316 SAFE_FREE(command->keyPath);
317 SAFE_FREE(command->padding);
318 ifapi_session_clean(context);
319 ifapi_cleanup_ifapi_object(command->key_object);
320 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
321 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
322 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
323 LOG_TRACE("finished");
324 return r;
325 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "fapi_policy.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24 #include "fapi_crypto.h"
25
26 /** One-Call function for Fapi_Unseal
27 *
28 * Unseals data from a seal in the FAPI metadata store.
29 *
30 * @param[in,out] context The FAPI_CONTEXT
31 * @param[in] path The path to the sealed data
32 * @param[out] data The decrypted data after unsealing. May be NULL
33 * @param[out] size The size of data in bytes. May be NULL
34 *
35 * @retval TSS2_RC_SUCCESS: if the function call was a success.
36 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
37 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
38 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not point to a sealed data object.
39 * @retval TSS2_FAPI_RC_BAD_VALUE: if the digestSize is zero.
40 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
41 * operation already pending.
42 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
43 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
44 * internal operations or return parameters.
45 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
46 * config file.
47 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
48 * this function needs to be called again.
49 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
50 * during authorization.
51 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
52 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
53 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the signature could not
54 * be verified
55 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
56 */
57 TSS2_RC
58 Fapi_Unseal(
59 FAPI_CONTEXT *context,
60 char const *path,
61 uint8_t **data,
62 size_t *size)
63 {
64 LOG_TRACE("called for context:%p", context);
65
66 TSS2_RC r, r2;
67
68 /* Check for NULL parameters */
69 check_not_null(context);
70 check_not_null(path);
71
72 /* Check whether TCTI and ESYS are initialized */
73 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
74 TSS2_FAPI_RC_NO_TPM);
75
76 /* If the async state automata of FAPI shall be tested, then we must not set
77 the timeouts of ESYS to blocking mode.
78 During testing, the mssim tcti will ensure multiple re-invocations.
79 Usually however the synchronous invocations of FAPI shall instruct ESYS
80 to block until a result is available. */
81 #ifndef TEST_FAPI_ASYNC
82 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
83 return_if_error_reset_state(r, "Set Timeout to blocking");
84 #endif /* TEST_FAPI_ASYNC */
85
86 r = Fapi_Unseal_Async(context, path);
87 return_if_error_reset_state(r, "Unseal");
88
89 do {
90 /* We wait for file I/O to be ready if the FAPI state automata
91 are in a file I/O state. */
92 r = ifapi_io_poll(&context->io);
93 return_if_error(r, "Something went wrong with IO polling");
94
95 /* Repeatedly call the finish function, until FAPI has transitioned
96 through all execution stages / states of this invocation. */
97 r = Fapi_Unseal_Finish(context, data, size);
98 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
99
100 /* Reset the ESYS timeout to non-blocking, immediate response. */
101 r2 = Esys_SetTimeout(context->esys, 0);
102 return_if_error(r2, "Set Timeout to non-blocking");
103
104 return_if_error_reset_state(r, "Unseal");
105
106 LOG_TRACE("finished");
107 return TSS2_RC_SUCCESS;
108 }
109
110 /** Asynchronous function for Fapi_Unseal
111 *
112 * Unseals data from a seal in the FAPI metadata store.
113 *
114 * Call Fapi_Unseal_Finish to finish the execution of this command.
115 *
116 * @param[in,out] context The FAPI_CONTEXT
117 * @param[in] path The path to the sealed data
118 *
119 * @retval TSS2_RC_SUCCESS: if the function call was a success.
120 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
121 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
122 * @retval TSS2_FAPI_RC_BAD_PATH: if path does not point to a sealed data object.
123 * @retval TSS2_FAPI_RC_BAD_VALUE: if the digestSize is zero.
124 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
125 * operation already pending.
126 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
127 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
128 * internal operations or return parameters.
129 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
130 * config file.
131 */
132 TSS2_RC
133 Fapi_Unseal_Async(
134 FAPI_CONTEXT *context,
135 char const *path)
136 {
137 LOG_TRACE("called for context:%p", context);
138 LOG_TRACE("path: %s", path);
139
140 TSS2_RC r;
141
142 /* Check for NULL parameters */
143 check_not_null(context);
144 check_not_null(path);
145
146 /* Helpful alias pointers */
147 IFAPI_Unseal * command = &context->cmd.Unseal;
148
149 /* Reset all context-internal session state information. */
150 r = ifapi_session_init(context);
151 return_if_error(r, "Initialize Unseal");
152
153 /* Copy parameters to context for use during _Finish. */
154 strdup_check(command->keyPath, path, r, error_cleanup);
155
156 /* Initialize the context state for this operation. */
157 context->state = UNSEAL_WAIT_FOR_KEY;
158 LOG_TRACE("finished");
159 return TSS2_RC_SUCCESS;
160
161 error_cleanup:
162 /* Cleanup duplicated input parameters that were copied before. */
163 SAFE_FREE(command->keyPath);
164 return r;
165 }
166
167 /** Asynchronous finish function for Fapi_Unseal
168 *
169 * This function should be called after a previous Fapi_Unseal_Async.
170 *
171 * @param[in,out] context The FAPI_CONTEXT
172 * @param[out] data The decrypted data after unsealing. May be NULL
173 * @param[out] size The size of data in bytes. May be NULL
174 *
175 * @retval TSS2_RC_SUCCESS: if the function call was a success.
176 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
177 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
178 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
179 * operation already pending.
180 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
181 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
182 * internal operations or return parameters.
183 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
184 * complete. Call this function again later.
185 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
186 * during authorization.
187 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
188 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
189 * the function.
190 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
191 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the signature could not
192 * be verified
193 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
194 */
195 TSS2_RC
196 Fapi_Unseal_Finish(
197 FAPI_CONTEXT *context,
198 uint8_t **data,
199 size_t *size)
200 {
201 LOG_TRACE("called for context:%p", context);
202
203 TSS2_RC r;
204 ESYS_TR auth_session;
205
206 /* Check for NULL parameters */
207 check_not_null(context);
208
209 /* Helpful alias pointers */
210 IFAPI_Unseal * command = &context->cmd.Unseal;
211
212 switch (context->state) {
213 statecase(context->state, UNSEAL_WAIT_FOR_KEY);
214 /* Load the key to be used for unsealing from the keystore. */
215 r = ifapi_load_key(context, command->keyPath,
216 &command->object);
217 return_try_again(r);
218 goto_if_error(r, "Fapi load key.", error_cleanup);
219
220 fallthrough;
221
222 statecase(context->state, UNSEAL_AUTHORIZE_OBJECT);
223 /* Authorize the session for use with with key. */
224 r = ifapi_authorize_object(context, command->object, &auth_session);
225 return_try_again(r);
226 goto_if_error(r, "Authorize sealed object.", error_cleanup);
227
228 /* Perform the unseal operation with the TPM. */
229 r = Esys_Unseal_Async(context->esys, command->object->handle,
230 auth_session,
231 ESYS_TR_NONE, ESYS_TR_NONE);
232 goto_if_error(r, "Error esys Unseal ", error_cleanup);
233
234 fallthrough;
235
236 statecase(context->state, UNSEAL_WAIT_FOR_UNSEAL);
237 r = Esys_Unseal_Finish(context->esys, &command->unseal_data);
238 return_try_again(r);
239 goto_if_error(r, "Unseal_Finish", error_cleanup);
240
241 /* Flush the used key from the TPM. */
242 r = Esys_FlushContext_Async(context->esys, command->object->handle);
243 goto_if_error(r, "Error Esys Flush ", error_cleanup);
244
245 fallthrough;
246
247 statecase(context->state, UNSEAL_WAIT_FOR_FLUSH);
248 r = Esys_FlushContext_Finish(context->esys);
249 return_try_again(r);
250 goto_if_error(r, "Unseal_Flush", error_cleanup);
251
252 /* Return the data as requested by the caller.
253 Duplicate the unseal_data as necessary. */
254 if (size)
255 *size = command->unseal_data->size;
256 if (data) {
257 *data = malloc(command->unseal_data->size);
258 goto_if_null2(*data, "Out of memory", r, TSS2_FAPI_RC_MEMORY, error_cleanup);
259
260 memcpy(*data, &command->unseal_data->buffer[0],
261 command->unseal_data->size);
262 }
263 SAFE_FREE(command->unseal_data);
264
265 fallthrough;
266
267 statecase(context->state, UNSEAL_CLEANUP)
268 /* Cleanup the session used for authentication. */
269 r = ifapi_cleanup_session(context);
270 try_again_or_error_goto(r, "Cleanup", error_cleanup);
271
272 context->state = _FAPI_STATE_INIT;
273 break;
274
275 statecasedefault(context->state);
276 }
277
278 error_cleanup:
279 /* Cleanup any intermediate results and state stored in the context. */
280 ifapi_cleanup_ifapi_object(command->object);
281 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
282 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
283 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
284 ifapi_session_clean(context);
285 SAFE_FREE(command->keyPath);
286 LOG_TRACE("finished");
287 return r;
288 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_util.h"
19 #include "tss2_esys.h"
20 #include "fapi_crypto.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 /** One-Call function for Fapi_VerifyQuote
26 *
27 * Verifies that the data returned by a quote is valid.
28 *
29 * @param[in,out] context The FAPI_CONTEXT
30 * @param[in] publicKeyPath The path to the signing key
31 * @param[in] qualifyingData The qualifying data nonce. May be NULL
32 * @param[in] qualifyingDataSize The size of qualifyingData in bytes. Must be 0
33 * if qualifyingData is NULL
34 * @param[in] quoteInfo The quote information
35 * @param[in] signature The quote's signature
36 * @param[in] signatureSize The size of signature in bytes
37 * @param[in] pcrLog The PCR's log. May be NULL
38 *
39 * @retval TSS2_RC_SUCCESS: if the function call was a success.
40 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, publicKeyPath, quoteInfo,
41 * or signature is NULL.
42 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
43 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if path does not map to a FAPI entity.
44 * @retval TSS2_FAPI_RC_BAD_KEY: if the entity at path is not a key, or is a key
45 * that is unsuitable for the requested operation.
46 * @retval TSS2_FAPI_RC_BAD_VALUE: if quoteInfo, pcrEventLog, qualifyingData, or
47 * signature is invalid.
48 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
49 * operation already pending.
50 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
51 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
52 * internal operations or return parameters.
53 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
54 * during authorization.
55 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
56 * this function needs to be called again.
57 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
58 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the signature could not
59 * be verified
60 */
61 TSS2_RC
62 Fapi_VerifyQuote(
63 FAPI_CONTEXT *context,
64 char const *publicKeyPath,
65 uint8_t const *qualifyingData,
66 size_t qualifyingDataSize,
67 char const *quoteInfo,
68 uint8_t const *signature,
69 size_t signatureSize,
70 char const *pcrLog)
71 {
72 LOG_TRACE("called for context:%p", context);
73
74 TSS2_RC r;
75
76 /* Check for NULL parameters */
77 check_not_null(context);
78 check_not_null(publicKeyPath);
79 check_not_null(quoteInfo);
80 check_not_null(signature);
81
82 r = Fapi_VerifyQuote_Async(context, publicKeyPath,
83 qualifyingData, qualifyingDataSize,
84 quoteInfo, signature,
85 signatureSize, pcrLog);
86 return_if_error_reset_state(r, "Key_VerifyQuote");
87
88 do {
89 /* We wait for file I/O to be ready if the FAPI state automata
90 are in a file I/O state. */
91 r = ifapi_io_poll(&context->io);
92 return_if_error(r, "Something went wrong with IO polling");
93
94 /* Repeatedly call the finish function, until FAPI has transitioned
95 through all execution stages / states of this invocation. */
96 r = Fapi_VerifyQuote_Finish(context);
97 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
98
99 return_if_error_reset_state(r, "Key_VerifyQuote");
100
101 LOG_TRACE("finished");
102 return TSS2_RC_SUCCESS;
103 }
104
105 /** Asynchronous function for Fapi_VerifyQuote
106 *
107 * Verifies that the data returned by a quote is valid.
108 * Call Fapi_VerifyQuote_Finish to finish the execution of this command.
109 *
110 * @param[in,out] context The FAPI_CONTEXT
111 * @param[in] publicKeyPath The path to the signing key
112 * @param[in] qualifyingData The qualifying data nonce. May be NULL
113 * @param[in] qualifyingDataSize The size of qualifyingData in bytes. Must be 0
114 * if qualifyingData is NULL
115 * @param[in] quoteInfo The quote information
116 * @param[in] signature The quote's signature
117 * @param[in] signatureSize The size of signature in bytes
118 * @param[in] pcrLog The PCR's log. May be NULL
119 *
120 * @retval TSS2_RC_SUCCESS: if the function call was a success.
121 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, publicKeyPath, quoteInfo,
122 * or signature is NULL.
123 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
124 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if path does not map to a FAPI entity.
125 * @retval TSS2_FAPI_RC_BAD_KEY: if the entity at path is not a key, or is a key
126 * that is unsuitable for the requested operation.
127 * @retval TSS2_FAPI_RC_BAD_VALUE: if quoteInfo, pcrEventLog, qualifyingData, or
128 * signature is invalid.
129 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
130 * operation already pending.
131 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
132 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
133 * internal operations or return parameters.
134 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
135 * during authorization.
136 */
137 TSS2_RC
138 Fapi_VerifyQuote_Async(
139 FAPI_CONTEXT *context,
140 char const *publicKeyPath,
141 uint8_t const *qualifyingData,
142 size_t qualifyingDataSize,
143 char const *quoteInfo,
144 uint8_t const *signature,
145 size_t signatureSize,
146 char const *pcrLog)
147 {
148 LOG_TRACE("called for context:%p", context);
149 LOG_TRACE("publicKeyPath: %s", publicKeyPath);
150 if (qualifyingData) {
151 LOGBLOB_TRACE(qualifyingData, qualifyingDataSize, "qualifyingData");
152 } else {
153 LOG_TRACE("qualifyingData: (null) qualifyingDataSize: %zi", qualifyingDataSize);
154 }
155 LOG_TRACE("quoteInfo: %s", quoteInfo);
156 if (signature) {
157 LOGBLOB_TRACE(signature, signatureSize, "signature");
158 } else {
159 LOG_TRACE("signature: (null) signatureSize: %zi", signatureSize);
160 }
161 LOG_TRACE("pcrLog: %s", pcrLog);
162
163 TSS2_RC r;
164
165 /* Check for NULL parameters */
166 check_not_null(context);
167 check_not_null(publicKeyPath);
168 check_not_null(quoteInfo);
169 check_not_null(signature);
170
171 /* Check for invalid parameters */
172 if (qualifyingData == NULL && qualifyingDataSize != 0) {
173 LOG_ERROR("qualifyingData is NULL but qualifyingDataSize is not 0");
174 return TSS2_FAPI_RC_BAD_VALUE;
175 }
176
177 /* Helpful alias pointers */
178 IFAPI_PCR * command = &context->cmd.pcr;
179
180 r = ifapi_non_tpm_mode_init(context);
181 return_if_error(r, "Initialize VerifyQuote");
182
183 /* Copy parameters to context for use during _Finish. */
184 uint8_t * signatureBuffer = malloc(signatureSize);
185 goto_if_null2(signatureBuffer, "Out of memory",
186 r, TSS2_FAPI_RC_MEMORY, error_cleanup);
187 memcpy(signatureBuffer, signature, signatureSize);
188 command->signature = signatureBuffer;
189 command->signatureSize = signatureSize;
190
191 strdup_check(command->keyPath, publicKeyPath, r, error_cleanup);
192 strdup_check(command->quoteInfo, quoteInfo, r, error_cleanup);
193 strdup_check(command->logData, pcrLog, r, error_cleanup);
194
195 if (qualifyingData != NULL) {
196 FAPI_COPY_DIGEST(&command->qualifyingData.buffer[0],
197 command->qualifyingData.size,
198 qualifyingData, qualifyingDataSize);
199 }
200
201 /* Load the key for verification from the keystore. */
202 r = ifapi_keystore_load_async(&context->keystore, &context->io, publicKeyPath);
203 return_if_error2(r, "Could not open: %s", publicKeyPath);
204
205 /* Initialize the context state for this operation. */
206 context->state = VERIFY_QUOTE_READ;
207 LOG_TRACE("finished");
208 return TSS2_RC_SUCCESS;
209
210 error_cleanup:
211 /* Cleanup duplicated input parameters that were copied before. */
212 SAFE_FREE(command->keyPath);
213 SAFE_FREE(signatureBuffer);
214 command->signature = NULL;
215 SAFE_FREE(command->quoteInfo);
216 SAFE_FREE(command->logData);
217 return r;
218 }
219
220 /** Asynchronous finish function for Fapi_VerifyQuote
221 *
222 * This function should be called after a previous Fapi_VerifyQuote_Async.
223 *
224 * @param[in,out] context The FAPI_CONTEXT
225 *
226 * @retval TSS2_RC_SUCCESS: if the function call was a success.
227 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
228 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
229 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
230 * operation already pending.
231 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
232 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
233 * internal operations or return parameters.
234 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
235 * complete. Call this function again later.
236 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
237 * the function.
238 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
239 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the signature could not
240 * be verified
241 */
242 TSS2_RC
243 Fapi_VerifyQuote_Finish(
244 FAPI_CONTEXT *context)
245 {
246 LOG_TRACE("called for context:%p", context);
247
248 TSS2_RC r;
249 IFAPI_OBJECT key_object;
250 TPM2B_ATTEST attest2b;
251 TPM2B_DIGEST pcr_digest;
252
253 /* Check for NULL parameters */
254 check_not_null(context);
255
256 /* Helpful alias pointers */
257 IFAPI_PCR * command = &context->cmd.pcr;
258
259 memset(&key_object, 0, sizeof(IFAPI_OBJECT));
260
261 switch (context->state) {
262 statecase(context->state, VERIFY_QUOTE_READ);
263 r = ifapi_keystore_load_finish(&context->keystore, &context->io, &key_object);
264 return_try_again(r);
265 return_if_error_reset_state(r, "read_finish failed");
266
267 /* Recalculate the quote-info and attest2b buffer. */
268 r = ifapi_get_quote_info(command->quoteInfo, &attest2b,
269 &command->fapi_quote_info);
270 goto_if_error(r, "Get quote info.", error_cleanup);
271
272 /* Verify the signature over the attest2b structure. */
273 r = ifapi_verify_signature_quote(&key_object,
274 command->signature,
275 command->signatureSize,
276 &attest2b.attestationData[0],
277 attest2b.size,
278 &command->fapi_quote_info.sig_scheme);
279 goto_if_error(r, "Verify signature.", error_cleanup);
280
281 /* If no logData was provided then the operation is done. */
282 if (!command->logData) {
283 context->state = _FAPI_STATE_INIT;
284 break;
285 }
286
287 /* If logData was provided then the pcr_digests need to be recalculated
288 and verified against the quote_info. */
289
290 /* Parse the logData JSON. */
291 command->event_list = json_tokener_parse(context->cmd.pcr.logData);
292 return_if_null(command->event_list, "Json error.", TSS2_FAPI_RC_BAD_VALUE);
293
294 /* Recalculate and verify the PCR digests. */
295 r = ifapi_calculate_pcr_digest(command->event_list,
296 &command->fapi_quote_info, &pcr_digest);
297
298 goto_if_error(r, "Verify event list.", error_cleanup);
299
300 context->state = _FAPI_STATE_INIT;
301 break;
302
303 statecasedefault(context->state);
304 }
305
306 error_cleanup:
307 /* Cleanup any intermediate results and state stored in the context. */
308 if (key_object.objectType)
309 ifapi_cleanup_ifapi_object(&key_object);
310 if (command->event_list)
311 json_object_put(command->event_list);
312 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
313 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
314 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
315 SAFE_FREE(command->keyPath);
316 SAFE_FREE(command->signature);
317 SAFE_FREE(command->quoteInfo);
318 SAFE_FREE(command->logData);
319 LOG_TRACE("finished");
320 return r;
321 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #include "tss2_fapi.h"
17 #include "fapi_crypto.h"
18 #include "fapi_int.h"
19 #include "fapi_util.h"
20 #include "tss2_esys.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 /** One-Call function for Fapi_VerifySignature
26 *
27 * Verifies a signature using a public key found in a keyPath.
28 *
29 * @param[in,out] context The FAPI_CONTEXT
30 * @param[in] keyPath The path to the verification public key
31 * @param[in] digest The that was signed. Must be already hashed
32 * @param[in] digestSize the size of digest in bytes
33 * @param[in] signature The signature to be verified
34 * @param[in] signatureSize The size of signature in bytes
35 *
36 * @retval TSS2_RC_SUCCESS: if the function call was a success.
37 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, keyPath, signature, or
38 * digest is NULL.
39 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
40 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if keyPath does not map to a FAPI object.
41 * @retval TSS2_FAPI_RC_BAD_KEY: if the object at publicKeyPath is not a key, or
42 * is a key that is unsuitable for the requested operation.
43 * @retval TSS2_FAPI_RC_BAD_VALUE: if signature is invalid (has the wrong format)
44 * or if digestSize is zero.
45 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED: if the signature fails to
46 * verify.
47 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
48 * operation already pending.
49 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
50 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
51 * internal operations or return parameters.
52 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
53 * during authorization.
54 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
55 * this function needs to be called again.
56 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
57 */
58 TSS2_RC
59 Fapi_VerifySignature(
60 FAPI_CONTEXT *context,
61 char const *keyPath,
62 uint8_t const *digest,
63 size_t digestSize,
64 uint8_t const *signature,
65 size_t signatureSize)
66 {
67 LOG_TRACE("called for context:%p", context);
68
69 TSS2_RC r;
70
71 /* Check for NULL parameters */
72 check_not_null(context);
73 check_not_null(keyPath);
74 check_not_null(digest);
75 check_not_null(signature);
76
77 r = Fapi_VerifySignature_Async(context, keyPath, digest, digestSize,
78 signature, signatureSize);
79 return_if_error_reset_state(r, "Key_VerifySignature");
80
81 do {
82 /* We wait for file I/O to be ready if the FAPI state automata
83 are in a file I/O state. */
84 r = ifapi_io_poll(&context->io);
85 return_if_error(r, "Something went wrong with IO polling");
86
87 /* Repeatedly call the finish function, until FAPI has transitioned
88 through all execution stages / states of this invocation. */
89 r = Fapi_VerifySignature_Finish(context);
90 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
91
92 return_if_error_reset_state(r, "Key_VerifySignature");
93
94 LOG_TRACE("finished");
95 return TSS2_RC_SUCCESS;
96 }
97
98 /** Asynchronous function for Fapi_VerifySignature
99 *
100 * Verifies a signature using a public key found in a keyPath.
101 *
102 * Call Fapi_VerifySignature_Finish to finish the execution of this command.
103 *
104 * @param[in,out] context The FAPI_CONTEXT
105 * @param[in] keyPath The path to the verification public key
106 * @param[in] digest The that was signed. Must be already hashed
107 * @param[in] digestSize the size of digest in bytes
108 * @param[in] signature The signature to be verified
109 * @param[in] signatureSize The size of signature in bytes
110 *
111 * @retval TSS2_RC_SUCCESS: if the function call was a success.
112 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, keyPath, signature, or
113 * digest is NULL.
114 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
115 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND: if keyPath does not map to a FAPI object.
116 * @retval TSS2_FAPI_RC_BAD_KEY: if the object at publicKeyPath is not a key, or
117 * is a key that is unsuitable for the requested operation.
118 * @retval TSS2_FAPI_RC_BAD_VALUE: if signature is invalid (has the wrong format)
119 * or if digestSize is zero.
120 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED: if the signature fails to
121 * verify.
122 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
123 * operation already pending.
124 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
125 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
126 * internal operations or return parameters.
127 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
128 * during authorization.
129 */
130 TSS2_RC
131 Fapi_VerifySignature_Async(
132 FAPI_CONTEXT *context,
133 char const *keyPath,
134 uint8_t const *digest,
135 size_t digestSize,
136 uint8_t const *signature,
137 size_t signatureSize)
138 {
139 LOG_TRACE("called for context:%p", context);
140 LOG_TRACE("keyPath: %s", keyPath);
141 if (digest) {
142 LOGBLOB_TRACE(digest, digestSize, "digest");
143 } else {
144 LOG_TRACE("digset: (null) digestSize: %zi", digestSize);
145 }
146 if (signature) {
147 LOGBLOB_TRACE(signature, signatureSize, "signature");
148 } else {
149 LOG_TRACE("signature: (null) sigantureSize: %zi", signatureSize);
150 }
151
152 TSS2_RC r;
153
154 /* Check for NULL parameters */
155 check_not_null(context);
156 check_not_null(keyPath);
157 check_not_null(digest);
158 check_not_null(signature);
159
160 /* Helpful alias pointers */
161 IFAPI_Key_VerifySignature * command = &context->cmd.Key_VerifySignature;
162
163 r = ifapi_non_tpm_mode_init(context);
164 return_if_error(r, "Initialize VerifySignature");
165
166 /* Copy parameters to context for use during _Finish. */
167 uint8_t * signatureBuffer = malloc(signatureSize);
168 uint8_t * digestBuffer = malloc(digestSize);
169 goto_if_null2(signatureBuffer, "Out of memory", r, TSS2_FAPI_RC_MEMORY,
170 error_cleanup);
171 goto_if_null2(digestBuffer, "Out of memory", r, TSS2_FAPI_RC_MEMORY,
172 error_cleanup);
173 memcpy(signatureBuffer, signature, signatureSize);
174 memcpy(digestBuffer, digest, digestSize);
175 command->signature = signatureBuffer;
176 command->digest = digestBuffer;
177 command->signatureSize = signatureSize;
178 command->digestSize = digestSize;
179 memset(&command->key_object, 0, sizeof(IFAPI_OBJECT));
180
181 /* Load the key for verification from the keystore. */
182 r = ifapi_keystore_load_async(&context->keystore, &context->io, keyPath);
183 goto_if_error2(r, "Could not open: %s", error_cleanup, keyPath);
184
185 /* Initialize the context state for this operation. */
186 LOG_TRACE("finished");
187 return TSS2_RC_SUCCESS;
188
189 error_cleanup:
190 /* Cleanup duplicated input parameters that were copied before. */
191 SAFE_FREE(signatureBuffer);
192 command->signature = NULL;
193 SAFE_FREE(digestBuffer);
194 command->digest = NULL;
195 return r;
196 }
197
198 /** Asynchronous finish function for Fapi_VerifySignature
199 *
200 * This function should be called after a previous Fapi_VerifySignature_Async.
201 *
202 * @param[in,out] context The FAPI_CONTEXT
203 *
204 * @retval TSS2_RC_SUCCESS: if the function call was a success.
205 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
206 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
207 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
208 * operation already pending.
209 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
210 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
211 * internal operations or return parameters.
212 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
213 * complete. Call this function again later.
214 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
215 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
216 * the function.
217 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the signature could not
218 * be verified
219 */
220 TSS2_RC
221 Fapi_VerifySignature_Finish(
222 FAPI_CONTEXT *context)
223 {
224 LOG_TRACE("called for context:%p", context);
225
226 TSS2_RC r;
227
228 /* Check for NULL parameters */
229 check_not_null(context);
230
231 /* Helpful alias pointers */
232 IFAPI_Key_VerifySignature * command = &context->cmd.Key_VerifySignature;
233
234 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
235 &command->key_object);
236 return_try_again(r);
237 return_if_error_reset_state(r, "read_finish failed");
238
239 /* Verify the signature using a helper that tests all known signature schemes. */
240 r = ifapi_verify_signature(&command->key_object, command->signature,
241 command->signatureSize, command->digest, command->digestSize);
242 goto_if_error(r, "Verify signature.", cleanup);
243
244 cleanup:
245 /* Cleanup any intermediate results and state stored in the context. */
246 if (command->key_object.objectType)
247 ifapi_cleanup_ifapi_object(&command->key_object);
248 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
249 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
250 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
251 SAFE_FREE(command->signature);
252 SAFE_FREE(command->digest);
253 LOG_TRACE("finished");
254 return r;
255 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include "tss2_mu.h"
11 #include "tss2_fapi.h"
12 #include "fapi_int.h"
13 #include "fapi_util.h"
14 #include "tss2_esys.h"
15 #include "fapi_policy.h"
16 #include "fapi_crypto.h"
17 #define LOGMODULE fapi
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** One-Call function for Fapi_WriteAuthorizeNv
22 *
23 * Write the policyDigest of a policy to an NV index so it can be used in policies
24 * containing PolicyAuthorizeNV elements.
25 *
26 * @param[in,out] context The FAPI_CONTEXT
27 * @param[in] nvPath The path of the NV index
28 * @param[in] policyPath The path of the new policy
29 *
30 * @retval TSS2_RC_SUCCESS: if the function call was a success.
31 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
32 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
33 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath or policyPath does not map to a
34 * FAPI policy or NV index.
35 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
36 * operation already pending.
37 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
38 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
39 * internal operations or return parameters.
40 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
41 * config file.
42 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
43 * during authorization.
44 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
45 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
46 * the function.
47 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
48 * this function needs to be called again.
49 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
50 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
51 */
52 TSS2_RC
53 Fapi_WriteAuthorizeNv(
54 FAPI_CONTEXT *context,
55 char const *nvPath,
56 char const *policyPath)
57 {
58 LOG_TRACE("called for context:%p", context);
59
60 TSS2_RC r, r2;
61
62 /* Check for NULL parameters */
63 check_not_null(context);
64 check_not_null(nvPath);
65 check_not_null(policyPath);
66
67 /* Check whether TCTI and ESYS are initialized */
68 return_if_null(context->esys, "Command can't be executed in none TPM mode.",
69 TSS2_FAPI_RC_NO_TPM);
70
71 /* If the async state automata of FAPI shall be tested, then we must not set
72 the timeouts of ESYS to blocking mode.
73 During testing, the mssim tcti will ensure multiple re-invocations.
74 Usually however the synchronous invocations of FAPI shall instruct ESYS
75 to block until a result is available. */
76 #ifndef TEST_FAPI_ASYNC
77 r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
78 return_if_error_reset_state(r, "Set Timeout to blocking");
79 #endif /* TEST_FAPI_ASYNC */
80
81 r = Fapi_WriteAuthorizeNv_Async(context, nvPath, policyPath);
82 return_if_error_reset_state(r, "WriteAuthorizeNV");
83
84 do {
85 /* We wait for file I/O to be ready if the FAPI state automata
86 are in a file I/O state. */
87 r = ifapi_io_poll(&context->io);
88 return_if_error(r, "Something went wrong with IO polling");
89
90 /* Repeatedly call the finish function, until FAPI has transitioned
91 through all execution stages / states of this invocation. */
92 r = Fapi_WriteAuthorizeNv_Finish(context);
93 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
94
95 /* Reset the ESYS timeout to non-blocking, immediate response. */
96 r2 = Esys_SetTimeout(context->esys, 0);
97 return_if_error(r2, "Set Timeout to non-blocking");
98
99 return_if_error_reset_state(r, "WriteAuthorizeNV");
100
101 LOG_TRACE("finished");
102 return TSS2_RC_SUCCESS;
103 }
104
105 /** Asynchronous function for Fapi_WriteAuthorizeNv
106 *
107 * Write the policyDigest of a policy to an NV index so it can be used in policies
108 * containing PolicyAuthorizeNV elements.
109 *
110 * Call Fapi_WriteAuthorizeNv_Finish to finish the execution of this command.
111 *
112 * @param[in,out] context The FAPI_CONTEXT
113 * @param[in] nvPath The path of the NV index
114 * @param[in] policyPath The path of the new policy
115 *
116 * @retval TSS2_RC_SUCCESS: if the function call was a success.
117 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
118 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
119 * @retval TSS2_FAPI_RC_BAD_PATH: if nvPath or policyPath does not map to a
120 * FAPI policy or NV index.
121 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
122 * operation already pending.
123 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
124 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
125 * internal operations or return parameters.
126 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
127 * config file.
128 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
129 * during authorization.
130 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
131 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
132 * the function.
133 */
134 TSS2_RC
135 Fapi_WriteAuthorizeNv_Async(
136 FAPI_CONTEXT *context,
137 char const *nvPath,
138 char const *policyPath)
139 {
140 LOG_TRACE("called for context:%p", context);
141 LOG_TRACE("nvPath: %s", nvPath);
142 LOG_TRACE("policyPath: %s", policyPath);
143
144 TSS2_RC r;
145
146 /* Check for NULL parameters */
147 check_not_null(context);
148 check_not_null(nvPath);
149 check_not_null(policyPath);
150
151 /* Helpful alias pointers */
152 IFAPI_api_WriteAuthorizeNv * command = &context->cmd.WriteAuthorizeNV;
153 IFAPI_NV_Cmds * nvCmd = &context->nv_cmd;
154
155 /* Reset all context-internal session state information. */
156 r = ifapi_session_init(context);
157 return_if_error(r, "Initialize WriterAuthorizeNv");
158
159 /* Copy parameters to context for use during _Finish. */
160 strdup_check(command->policyPath, policyPath, r, error_cleanup);
161 strdup_check(nvCmd->nvPath, nvPath, r, error_cleanup);
162
163 /* Load the metadata for the NV index to be written to from the keystore. */
164 r = ifapi_keystore_load_async(&context->keystore, &context->io, nvCmd->nvPath);
165 goto_if_error2(r, "Could not open: %s", error_cleanup, nvCmd->nvPath);
166
167 /* Initialize the context state for this operation. */
168 context->state = WRITE_AUTHORIZE_NV_READ_NV;
169 LOG_TRACE("finished");
170 return TSS2_RC_SUCCESS;
171
172 error_cleanup:
173 /* Cleanup duplicated input parameters that were copied before. */
174 SAFE_FREE(command->policyPath);
175 SAFE_FREE(nvCmd->nvPath);
176 return r;
177 }
178
179 /** Asynchronous finish function for Fapi_WriteAuthorizeNv
180 *
181 * This function should be called after a previous Fapi_WriteAuthorizeNv_Async.
182 *
183 * @param[in,out] context The FAPI_CONTEXT
184 *
185 * @retval TSS2_RC_SUCCESS: if the function call was a success.
186 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
187 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
188 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
189 * operation already pending.
190 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
191 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
192 * internal operations or return parameters.
193 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
194 * complete. Call this function again later.
195 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
196 * the function.
197 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
198 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
199 * during authorization.
200 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
201 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
202 */
203 TSS2_RC
204 Fapi_WriteAuthorizeNv_Finish(
205 FAPI_CONTEXT *context)
206 {
207 LOG_TRACE("called for context:%p", context);
208
209 TSS2_RC r;
210 const size_t maxNvSize = sizeof(TPMU_HA) + sizeof(TPMI_ALG_HASH);
211 BYTE nvBuffer[maxNvSize];
212 size_t offset = 0;
213
214 /* Check for NULL parameters */
215 check_not_null(context);
216
217 /* Helpful alias pointers */
218 IFAPI_api_WriteAuthorizeNv * command = &context->cmd.WriteAuthorizeNV;
219 IFAPI_NV_Cmds * nvCmd = &context->nv_cmd;
220 IFAPI_OBJECT *object = &nvCmd->nv_object;
221 TPMI_ALG_HASH hashAlg;
222 TPMS_POLICY * policy = &context->policy.policy;
223
224 switch (context->state) {
225 statecase(context->state, WRITE_AUTHORIZE_NV_READ_NV)
226 /* First check whether the file in object store can be updated. */
227 r = ifapi_keystore_check_writeable(&context->keystore, &context->io,
228 nvCmd->nvPath);
229 goto_if_error_reset_state(r,
230 "Check whether update object store is possible.", error_cleanup);
231
232 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
233 return_try_again(r);
234 return_if_error_reset_state(r, "read_finish failed");
235
236 ifapi_cleanup_ifapi_object(object);
237
238 /* Initialize the NV index object to be used with esys. */
239 r = ifapi_initialize_object(context->esys, object);
240 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
241
242 fallthrough;
243
244 statecase(context->state, WRITE_AUTHORIZE_NV_CALCULATE_POLICY)
245 /* Calculate the policy digest for the referenced policy. */
246 hashAlg = object->misc.nv.public.nvPublic.nameAlg;
247 r = ifapi_calculate_tree(context, command->policyPath,
248 policy, hashAlg, &command->digest_idx,
249 &command->hash_size);
250 if (r != TSS2_RC_SUCCESS) {
251 ifapi_cleanup_ifapi_object(object);
252 }
253 return_try_again(r);
254 goto_if_error(r, "Fapi calculate tree.", error_cleanup);
255
256 fallthrough;
257
258 statecase(context->state, WRITE_AUTHORIZE_NV_WRITE_NV_RAM_PREPARE)
259
260 /* Copy hash alg followed by digest into a buffer to be written to NV ram */
261 r = Tss2_MU_TPMI_ALG_HASH_Marshal(
262 object->misc.nv.public.nvPublic.nameAlg,
263 &nvBuffer[0], maxNvSize, &offset);
264 goto_if_error_reset_state(r, "FAPI marshal hash alg", error_cleanup);
265
266 void * currentDigest =
267 &policy->policyDigests.digests[command->digest_idx].digest;
268 memcpy(&nvBuffer[offset], currentDigest, command->hash_size);
269
270 /* Store these data in the context to be used for re-entry on nv_write. */
271 nvCmd->data = &nvBuffer[0];
272 nvCmd->numBytes = command->hash_size + sizeof(TPMI_ALG_HASH);
273 fallthrough;
274
275 statecase(context->state, WRITE_AUTHORIZE_NV_WRITE_NV_RAM)
276 /* Perform the actual NV Write operation. */
277 r = ifapi_nv_write(context, nvCmd->nvPath, 0,
278 nvCmd->data, context->nv_cmd.numBytes);
279 return_try_again(r);
280 goto_if_error_reset_state(r, " FAPI NV Write", error_cleanup);
281
282 /* Perform esys serialization if necessary */
283 r = ifapi_esys_serialize_object(context->esys, object);
284 goto_if_error(r, "Prepare serialization", error_cleanup);
285
286 /* Save NV object to ensure that changed flags are updated. */
287 r = ifapi_keystore_store_async(&context->keystore, &context->io,
288 nvCmd->nvPath, object);
289 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
290 nvCmd->nvPath);
291
292 fallthrough;
293
294 statecase(context->state, WRITE_AUTHORIZE_NV_WRITE_OBJCECT)
295 /* Finish writing the NV object to the key store */
296 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
297 return_try_again(r);
298 return_if_error_reset_state(r, "write_finish failed");
299
300 fallthrough;
301
302 statecase(context->state, WRITE_AUTHORIZE_NV_WRITE_POLICY_PREPARE)
303 r = ifapi_policy_store_store_async(&context->pstore, &context->io,
304 command->policyPath, policy);
305 goto_if_error_reset_state(r, "Could not open: %s", error_cleanup,
306 command->policyPath);
307 fallthrough;
308
309 statecase(context->state, WRITE_AUTHORIZE_NV_WRITE_POLICY)
310 /* Save policy with computed digest */
311 r = ifapi_policy_store_store_finish(&context->pstore, &context->io);
312 return_try_again(r);
313 return_if_error_reset_state(r, "write_finish failed");
314
315 fallthrough;
316
317 statecase(context->state, WRITE_AUTHORIZE_NV_CLEANUP)
318 /* Cleanup the session used for authorizing access to the NV index. */
319 r = ifapi_cleanup_session(context);
320 try_again_or_error_goto(r, "Cleanup", error_cleanup);
321 context->state = _FAPI_STATE_INIT;
322 break;
323
324 statecasedefault(context->state);
325 }
326
327 error_cleanup:
328 /* Cleanup any intermediate results and state stored in the context. */
329 SAFE_FREE(command->policyPath);
330 SAFE_FREE(nvCmd->nvPath);
331 ifapi_session_clean(context);
332 ifapi_cleanup_policy(policy);
333 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
334 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
335 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
336 ifapi_cleanup_ifapi_object(object);
337 LOG_TRACE("finished");
338 return r;
339 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #ifndef NO_DL
11 #include <dlfcn.h>
12 #endif /* NO_DL */
13 #include <stdlib.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18
19 #define LOGMODULE fapi
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 /**
24 * This function registers a callback that will be invoked whenever the FAPI has
25 * to decide which branch of a Policy-OR policy to use to authorize a particular
26 * FAPI operation.
27 *
28 * @param[in,out] context The FAPI_CONTEXT
29 * @param[in] callback The callback function for branch selection
30 * @param[in] userData A pointer that is provided to all callback invocations
31 *
32 * @retval TSS2_RC_SUCCESS: if the function call was a success.
33 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or callback is NULL.
34 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
35 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
36 * internal operations or return parameters.
37 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the synchronous or Async functions are
38 * called while the context has another asynchronous operation
39 * outstanding, or the Finish function is called while the context does
40 * not have an appropriate asynchronous operation outstanding.
41 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
42 */
43 TSS2_RC
44 Fapi_SetBranchCB(
45 FAPI_CONTEXT *context,
46 Fapi_CB_Branch callback,
47 void *userData)
48 {
49 LOG_TRACE("called for context:%p", context);
50 LOG_TRACE("Callback %p Userdata %p", callback, userData);
51
52 /* Check for NULL parameters */
53 check_not_null(context);
54 check_not_null(callback);
55
56 /* Store the callback and userdata pointer. */
57 context->callbacks.branch = callback;
58 context->callbacks.branchData = userData;
59
60 LOG_TRACE("finished");
61 return TSS2_RC_SUCCESS;
62 }
63
64 /**
65 * This function registers an application-defined function as a callback to
66 * allow the TSS to get authorization values from the application.
67 *
68 * @param[in,out] context The FAPI_CONTEXT
69 * @param[in] callback The callback function for auth value retrieval
70 * @param[in] userData A pointer that is provided to all callback invocations
71 *
72 * @retval TSS2_RC_SUCCESS: if the function call was a success.
73 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or callback is NULL.
74 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
75 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
76 * internal operations or return parameters.
77 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the synchronous or Async functions are
78 * called while the context has another asynchronous operation
79 * outstanding, or the Finish function is called while the context does
80 * not have an appropriate asynchronous operation outstanding.
81 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
82 */
83 TSS2_RC
84 Fapi_SetAuthCB(
85 FAPI_CONTEXT *context,
86 Fapi_CB_Auth callback,
87 void *userData)
88 {
89 LOG_TRACE("called for context:%p", context);
90 LOG_TRACE("Callback %p Userdata %p", callback, userData);
91
92 /* Check for NULL parameters */
93 check_not_null(context);
94 check_not_null(callback);
95
96 /* Store the callback and userdata pointer. */
97 context->callbacks.auth = callback;
98 context->callbacks.authData = userData;
99
100 LOG_TRACE("finished");
101 return TSS2_RC_SUCCESS;
102 }
103
104 /**
105 * Fapi_SetSignCB() registers an application-defined function as a callback to
106 * allow the FAPI to get signatures authorizing use of TPM objects.
107 *
108 * @param[in,out] context The FAPI_CONTEXT
109 * @param[in] callback The callback function for signing selection
110 * @param[in] userData A pointer that is provided to all callback invocations
111 *
112 * @retval TSS2_RC_SUCCESS: if the function call was a success.
113 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or callback is NULL.
114 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
115 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
116 * internal operations or return parameters.
117 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the synchronous or Async functions are
118 * called while the context has another asynchronous operation
119 * outstanding, or the Finish function is called while the context does
120 * not have an appropriate asynchronous operation outstanding.
121 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
122 */
123 TSS2_RC
124 Fapi_SetSignCB(
125 FAPI_CONTEXT *context,
126 Fapi_CB_Sign callback,
127 void *userData)
128 {
129 LOG_TRACE("called for context:%p", context);
130 LOG_TRACE("Callback %p Userdata %p", callback, userData);
131
132 /* Check for NULL parameters */
133 check_not_null(context);
134 check_not_null(callback);
135
136 /* Store the callback and userdata pointer. */
137 context->callbacks.sign = callback;
138 context->callbacks.signData = userData;
139
140 LOG_TRACE("finished");
141 return TSS2_RC_SUCCESS;
142 }
143
144
145 /**
146 * Fapi_SetActionCB() registers an application-defined function as a callback
147 * that shall be called back upon encountering a policy action element.
148 *
149 * @param[in,out] context The FAPI_CONTEXT
150 * @param[in] callback The callback function for branch selection
151 * @param[in] userData A pointer that is provided to all callback invocations
152 *
153 * @retval TSS2_RC_SUCCESS: if the function call was a success.
154 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or callback is NULL.
155 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
156 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
157 * internal operations or return parameters.
158 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the synchronous or Async functions are
159 * called while the context has another asynchronous operation
160 * outstanding, or the Finish function is called while the context does
161 * not have an appropriate asynchronous operation outstanding.
162 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
163 */
164 TSS2_RC
165 Fapi_SetPolicyActionCB(
166 FAPI_CONTEXT *context,
167 Fapi_CB_PolicyAction callback,
168 void *userData)
169 {
170 LOG_TRACE("called for context:%p", context);
171 LOG_TRACE("Callback %p Userdata %p", callback, userData);
172
173 /* Check for NULL parameters */
174 check_not_null(context);
175 check_not_null(callback);
176
177 /* Store the callback and userdata pointer. */
178 context->callbacks.action = callback;
179 context->callbacks.actionData = userData;
180
181 LOG_TRACE("finished");
182 return TSS2_RC_SUCCESS;
183 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef FAPI_CERTIFICATES_H
6 #define FAPI_CERTIFICATES_H
7
8 static char * root_cert_list[] = {
9 /* IFX RSA root certificate */
10 "-----BEGIN CERTIFICATE-----\n"
11 "MIIFqzCCA5OgAwIBAgIBAzANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJERTEh\n"
12 "MB8GA1UECgwYSW5maW5lb24gVGVjaG5vbG9naWVzIEFHMRswGQYDVQQLDBJPUFRJ\n"
13 "R0EoVE0pIERldmljZXMxKDAmBgNVBAMMH0luZmluZW9uIE9QVElHQShUTSkgUlNB\n"
14 "IFJvb3QgQ0EwHhcNMTMwNzI2MDAwMDAwWhcNNDMwNzI1MjM1OTU5WjB3MQswCQYD\n"
15 "VQQGEwJERTEhMB8GA1UECgwYSW5maW5lb24gVGVjaG5vbG9naWVzIEFHMRswGQYD\n"
16 "VQQLDBJPUFRJR0EoVE0pIERldmljZXMxKDAmBgNVBAMMH0luZmluZW9uIE9QVElH\n"
17 "QShUTSkgUlNBIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n"
18 "AQC7E+gc0B5T7awzux66zMMZMTtCkPqGv6a3NVx73ICg2DSwnipFwBiUl9soEodn\n"
19 "25SVVN7pqmvKA2gMTR5QexuYS9PPerfRZrBY00xyFx84V+mIRPg4YqUMLtZBcAwr\n"
20 "R3GO6cffHp20SBH5ITpuqKciwb0v5ueLdtZHYRPq1+jgy58IFY/vACyF/ccWZxUS\n"
21 "JRNSe4ruwBgI7NMWicxiiWQmz1fE3e0mUGQ1tu4M6MpZPxTZxWzN0mMz9noj1oIT\n"
22 "ZUnq/drN54LHzX45l+2b14f5FkvtcXxJ7OCkI7lmWIt8s5fE4HhixEgsR2RX5hzl\n"
23 "8XiHiS7uD3pQhBYSBN5IBbVWREex1IUat5eAOb9AXjnZ7ivxJKiY/BkOmrNgN8k2\n"
24 "7vOS4P81ix1GnXsjyHJ6mOtWRC9UHfvJcvM3U9tuU+3dRfib03NGxSPnKteL4SP1\n"
25 "bdHfiGjV3LIxzFHOfdjM2cvFJ6jXg5hwXCFSdsQm5e2BfT3dWDBSfR4h3Prpkl6d\n"
26 "cAyb3nNtMK3HR5yl6QBuJybw8afHT3KRbwvOHOCR0ZVJTszclEPcM3NQdwFlhqLS\n"
27 "ghIflaKSPv9yHTKeg2AB5q9JSG2nwSTrjDKRab225+zJ0yylH5NwxIBLaVHDyAEu\n"
28 "81af+wnm99oqgvJuDKSQGyLf6sCeuy81wQYO46yNa+xJwQIDAQABo0IwQDAdBgNV\n"
29 "HQ4EFgQU3LtWq/EY/KaadREQZYQSntVBkrkwDgYDVR0PAQH/BAQDAgAGMA8GA1Ud\n"
30 "EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAGHTBUx3ETIXYJsaAgb2pyyN\n"
31 "UltVL2bKzGMVSsnTCrXUU8hKrDQh3jNIMrS0d6dU/fGaGJvehxmmJfjaN/IFWA4M\n"
32 "BdZEnpAe2fJEP8vbLa/QHVfsAVuotLD6QWAqeaC2txpxkerveoV2JAwj1jrprT4y\n"
33 "rkS8SxZuKS05rYdlG30GjOKTq81amQtGf2NlNiM0lBB/SKTt0Uv5TK0jIWbz2WoZ\n"
34 "gGut7mF0md1rHRauWRcoHQdxWSQTCTtgoQzeBj4IS6N3QxQBKV9LL9UWm+CMIT7Y\n"
35 "np8bSJ8oW4UdpSuYWe1ZwSjZyzDiSzpuc4gTS6aHfMmEfoVwC8HN03/HD6B1Lwo2\n"
36 "DvEaqAxkya9IYWrDqkMrEErJO6cqx/vfIcfY/8JYmUJGTmvVlaODJTwYwov/2rjr\n"
37 "la5gR+xrTM7dq8bZimSQTO8h6cdL6u+3c8mGriCQkNZIZEac/Gdn+KwydaOZIcnf\n"
38 "Rdp3SalxsSp6cWwJGE4wpYKB2ClM2QF3yNQoTGNwMlpsxnU72ihDi/RxyaRTz9OR\n"
39 "pubNq8Wuq7jQUs5U00ryrMCZog1cxLzyfZwwCYh6O2CmbvMoydHNy5CU3ygxaLWv\n"
40 "JpgZVHN103npVMR3mLNa3QE+5MFlBlP3Mmystu8iVAKJas39VO5y5jad4dRLkwtM\n"
41 "6sJa8iBpdRjZrBp5sJBI\n"
42 "-----END CERTIFICATE-----\n",
43
44 /* IFX ECC root certificate */
45 "-----BEGIN CERTIFICATE-----\n"
46 "MIICWzCCAeKgAwIBAgIBBDAKBggqhkjOPQQDAzB3MQswCQYDVQQGEwJERTEhMB8G\n"
47 "A1UECgwYSW5maW5lb24gVGVjaG5vbG9naWVzIEFHMRswGQYDVQQLDBJPUFRJR0Eo\n"
48 "VE0pIERldmljZXMxKDAmBgNVBAMMH0luZmluZW9uIE9QVElHQShUTSkgRUNDIFJv\n"
49 "b3QgQ0EwHhcNMTMwNzI2MDAwMDAwWhcNNDMwNzI1MjM1OTU5WjB3MQswCQYDVQQG\n"
50 "EwJERTEhMB8GA1UECgwYSW5maW5lb24gVGVjaG5vbG9naWVzIEFHMRswGQYDVQQL\n"
51 "DBJPUFRJR0EoVE0pIERldmljZXMxKDAmBgNVBAMMH0luZmluZW9uIE9QVElHQShU\n"
52 "TSkgRUNDIFJvb3QgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQm1HxLVgvAu1q2\n"
53 "GM+ymTz12zdTEu0JBVG9CdsVEJv/pE7pSWOlsG3YwU792YAvjSy7zL+WtDK40KGe\n"
54 "Om8bSWt46QJ00MQUkYxz6YqXbb14BBr06hWD6u6IMBupNkPd9pKjQjBAMB0GA1Ud\n"
55 "DgQWBBS0GIXISkrFEnryQDnexPWLHn5K0TAOBgNVHQ8BAf8EBAMCAAYwDwYDVR0T\n"
56 "AQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjA6QZcV8DjjbPuKjKDZQmTRywZk\n"
57 "MAn8wE6kuW3EouVvBt+/2O+szxMe4vxj8R6TDCYCMG7c9ov86ll/jDlJb/q0L4G+\n"
58 "+O3Bdel9P5+cOgzIGANkOPEzBQM3VfJegfnriT/kaA==\n"
59 "-----END CERTIFICATE-----\n",
60
61 /* Intel root certificate */
62 "-----BEGIN CERTIFICATE-----\n"
63 "MIICdzCCAh6gAwIBAgIUB+dPf7a3IyJGO923z34oQLRP7pwwCgYIKoZIzj0EAwIw\n"
64 "gYcxCzAJBgNVBAYMAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwLU2FudGEgQ2xh\n"
65 "cmExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0aW9uMSEwHwYDVQQLDBhUUE0gRUsg\n"
66 "cm9vdCBjZXJ0IHNpZ25pbmcxFjAUBgNVBAMMDXd3dy5pbnRlbC5jb20wHhcNMTQw\n"
67 "MTE1MDAwMDAwWhcNNDkxMjMxMjM1OTU5WjCBhzELMAkGA1UEBgwCVVMxCzAJBgNV\n"
68 "BAgMAkNBMRQwEgYDVQQHDAtTYW50YSBDbGFyYTEaMBgGA1UECgwRSW50ZWwgQ29y\n"
69 "cG9yYXRpb24xITAfBgNVBAsMGFRQTSBFSyByb290IGNlcnQgc2lnbmluZzEWMBQG\n"
70 "A1UEAwwNd3d3LmludGVsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJR9\n"
71 "gVEsjUrMb+E/dl19ywJsKZDnghmwVyG16dAfQ0Pftp1bjhtPEGEguvbLGRRopKWH\n"
72 "VscAOlTFnvCHq+6/9/SjZjBkMB8GA1UdIwQYMBaAFOhSBcJP2NLVpSFHFrbODHtb\n"
73 "uncPMB0GA1UdDgQWBBToUgXCT9jS1aUhRxa2zgx7W7p3DzASBgNVHRMBAf8ECDAG\n"
74 "AQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAgNHADBEAiAldFScWQ6L\n"
75 "PQgW/YT+2GILcATEA2TgzASaCrG+AzL6FgIgLH8ABRzm028hRYR/JZVGkHiomzYX\n"
76 "VILmTjHwSL7uZBU=\n"
77 "-----END CERTIFICATE-----",
78
79 /* STM RSA root certificate */
80 "-----BEGIN CERTIFICATE-----\n"
81 "MIIEDDCCAvSgAwIBAgILBAAAAAABIsFs834wDQYJKoZIhvcNAQELBQAwgYcxOzA5\n"
82 "BgNVBAsTMkdsb2JhbFNpZ24gVHJ1c3RlZCBDb21wdXRpbmcgQ2VydGlmaWNhdGUg\n"
83 "QXV0aG9yaXR5MRMwEQYDVQQKEwpHbG9iYWxTaWduMTMwMQYDVQQDEypHbG9iYWxT\n"
84 "aWduIFRydXN0ZWQgUGxhdGZvcm0gTW9kdWxlIFJvb3QgQ0EwHhcNMDkwNzI4MTIw\n"
85 "MDAwWhcNMzkxMjMxMjM1OTU5WjBKMQswCQYDVQQGEwJDSDEeMBwGA1UEChMVU1RN\n"
86 "aWNyb2VsZWN0cm9uaWNzIE5WMRswGQYDVQQDExJTVE0gVFBNIEVLIFJvb3QgQ0Ew\n"
87 "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDxBLG5wcB9J0MsiJMreoWQ\n"
88 "l21bBN12SSGZPJ3HoPjzcrzAz6SPy+TrFmZ6eUVspsFL/23wdPprqTUtDHi+C2pw\n"
89 "k/3dF3/Rb2t/yHgiPlbCshYpi5f/rJ7nzbQ1ca2LzX3saBe53VfNQQV0zd5uM0DT\n"
90 "SrmAKU1RIAj2WlZFWXoN4NWTyRtqT5suPHa2y8FlCWMZKlS0FiY4pfM20b5YQ+EL\n"
91 "4zqb9zN53u/TdYZegrfSlc30Nl9G13Mgi+8rtPFKwsxx05EBbhVroH7aKVI1djsf\n"
92 "E1MVrUzw62PHik3xlzznXML8OjY//xKeiCWcsApuGCaIAf7TsTRi2l8DNB3rCr1X\n"
93 "AgMBAAGjgbQwgbEwDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQEw\n"
94 "HQYDVR0OBBYEFG/mxWwHt2yLCoGSg1zLQR72jtEnMEsGA1UdIAREMEIwQAYJKwYB\n"
95 "BAGgMgFaMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2xvYmFsc2lnbi5uZXQv\n"
96 "cmVwb3NpdG9yeS8wHwYDVR0jBBgwFoAUHiNj8IW19iVO7RrAUL5lfMfUFXowDQYJ\n"
97 "KoZIhvcNAQELBQADggEBAFrKpwFmRh7BGdpPZWc1Y6wIbdTAF6T+q1KwDJcyAjgJ\n"
98 "qThFp3xTAt3tvyVrCRf7T/YARYE24DNa0iFaXsIXeQASDYHJjAZ6LQTslYBeRYLb\n"
99 "C9v8ZE2ocKSCiC8ALYlJWk39Wob0H1Lk6l2zcUo3oKczGiAcRrlmwV496wvGyted\n"
100 "2RBcLZro7yhOOGr9KMabV14fNl0lG+31J1nWI2hgTqh53GXg1QH2YpggD3b7UbVm\n"
101 "c6GZaX37N3z15XfQafuAfHt10kYCNdePzC9tOwirHIsO8lrxoNlzOSxX8SqQGbBI\n"
102 "+kWoe5+SY3gdOGGDQKIdw3W1poMN8bQ5x7XFcgVMwVU=\n"
103 "-----END CERTIFICATE-----\n",
104
105 /* STM ECC root certificate */
106 "-----BEGIN CERTIFICATE-----\n"
107 "MIICyDCCAk+gAwIBAgIORyzLp/OdsAvb9r+66LowCgYIKoZIzj0EAwMwgYsxOzA5\n"
108 "BgNVBAsTMkdsb2JhbFNpZ24gVHJ1c3RlZCBDb21wdXRpbmcgQ2VydGlmaWNhdGUg\n"
109 "QXV0aG9yaXR5MRMwEQYDVQQKEwpHbG9iYWxTaWduMTcwNQYDVQQDEy5HbG9iYWxT\n"
110 "aWduIFRydXN0ZWQgUGxhdGZvcm0gTW9kdWxlIEVDQyBSb290IENBMB4XDTE1MTAy\n"
111 "ODAwMDAwMFoXDTM4MDExOTAzMTQwN1owTjELMAkGA1UEBhMCQ0gxHjAcBgNVBAoT\n"
112 "FVNUTWljcm9lbGVjdHJvbmljcyBOVjEfMB0GA1UEAxMWU1RNIFRQTSBFQ0MgUm9v\n"
113 "dCBDQSAwMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABG7/OLXMiprQQHwNnkpT6aqG\n"
114 "zOGLcbbAgUtyjlXOZtuv0GB0ttJ6fwMwgFtt8RKlko8Bwn89/BoZOUcI4ne8ddRS\n"
115 "oqE6StnU3I13qqjalToq3Rnz61Omn6NErK1pxUe3j6OBtTCBsjAOBgNVHQ8BAf8E\n"
116 "BAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUIJJWPAtDqAVyUwMp\n"
117 "BxwH4OvsAwQwHwYDVR0jBBgwFoAUYT78EZkKf7CpW5CgJl4pYUe3MAMwTAYDVR0g\n"
118 "BEUwQzBBBgkrBgEEAaAyAVowNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xv\n"
119 "YmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCgYIKoZIzj0EAwMDZwAwZAIwWnuUAzwy\n"
120 "vHUhHehymKTZ2QcPUwHX0LdcVTac4ohyEL3zcuv/dM0BN62kFxHgBOhWAjAIxt9i\n"
121 "50yAxy0Z/MeV2NTXqKpLwdhWNuzOSFZnzRKsh9MxY3zj8nebDNlHTDGSMR0=\n"
122 "-----END CERTIFICATE-----",
123
124 /* NTC_TPM_EK_Root_CA_01 */
125 "-----BEGIN CERTIFICATE-----\n"
126 "MIIDSjCCAjKgAwIBAgIGAK3jXfbVMA0GCSqGSIb3DQEBBQUAMFIxUDAcBgNVBAMT\n"
127 "FU5UQyBUUE0gRUsgUm9vdCBDQSAwMTAlBgNVBAoTHk51dm90b24gVGVjaG5vbG9n\n"
128 "eSBDb3Jwb3JhdGlvbjAJBgNVBAYTAlRXMB4XDTEyMDcxMTE2MjkzMFoXDTMyMDcx\n"
129 "MTE2MjkzMFowUjFQMBwGA1UEAxMVTlRDIFRQTSBFSyBSb290IENBIDAxMCUGA1UE\n"
130 "ChMeTnV2b3RvbiBUZWNobm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwggEi\n"
131 "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDoNqxhtD4yUtXhqKQGGZemoKJy\n"
132 "uj1RnWvmNgzItLeejNU8B6fOnpMQyoS4K72tMhhFRK2jV9RYzyJMSjEwyX0ASTO1\n"
133 "2yMti2UJQS60d36eGwk8WLgrFnnITlemshi01h9t1MOmay3TO1LLH/3/VDKJ+jbd\n"
134 "cbfIO2bBquN8r3/ojYUaNSPj6pK1mmsMoJXF4dGRSEwb/4ozBIw5dugm1MEq4Zj3\n"
135 "GZ0YPg5wyLRugQbt7DkUOX4FGuK5p/C0u5zX8u33EGTrDrRz3ye3zO+aAY1xXF/m\n"
136 "qwEqgxX5M8f0/DXTTO/CfeIksuPeOzujFtXfi5Cy64eeIZ0nAUG3jbtnGjoFAgMB\n"
137 "AAGjJjAkMA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMA0GCSqG\n"
138 "SIb3DQEBBQUAA4IBAQBBQznOPJAsD4Yvyt/hXtVJSgBX/+rRfoaqbdt3UMbUPJYi\n"
139 "pUoTUgaTx02DVRwommO+hLx7CS++1F2zorWC8qQyvNbg7iffQbbjWitt8NPE6kCr\n"
140 "q0Y5g7M/LkQDd5N3cFfC15uFJOtlj+A2DGzir8dlXU/0qNq9dBFbi+y+Y3rAT+wK\n"
141 "fktmN82UT861wTUzDvnXO+v7H5DYXjUU8kejPW6q+GgsccIbVTOdHNNWbMrcD9yf\n"
142 "oS91nMZ/+/n7IfFWXNN82qERsrvOFCDsbIzUOR30N0IP++oqGfwAbKFfCOCFUz6j\n"
143 "jpXUdJlh22tp12UMsreibmi5bsWYBgybwSbRgvzE\n"
144 "-----END CERTIFICATE-----\n",
145
146 /* NTC_TPM_EK_Root_CA_02 */
147 "-----BEGIN CERTIFICATE-----\n"
148 "MIIDSjCCAjKgAwIBAgIGAPadBmPZMA0GCSqGSIb3DQEBBQUAMFIxUDAcBgNVBAMT\n"
149 "FU5UQyBUUE0gRUsgUm9vdCBDQSAwMjAlBgNVBAoTHk51dm90b24gVGVjaG5vbG9n\n"
150 "eSBDb3Jwb3JhdGlvbjAJBgNVBAYTAlRXMB4XDTEyMDcxMTE2MzMyNFoXDTMyMDcx\n"
151 "MTE2MzMyNFowUjFQMBwGA1UEAxMVTlRDIFRQTSBFSyBSb290IENBIDAyMCUGA1UE\n"
152 "ChMeTnV2b3RvbiBUZWNobm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwggEi\n"
153 "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSagWxaANT1YA2YUSN7sq7yzOT\n"
154 "1ymbIM+WijhE5AGcLwLFoJ9fmaQrYL6fAW2EW/Q3yu97Q9Ysr8yYZ2XCCfxfseEr\n"
155 "Vs80an8Nk6LkTDz8+0Hm0Cct0klvNUAZEIvWpmgHZMvGijXyOcp4z494d8B28Ynb\n"
156 "I7x0JMXZZQQKQi+WfuHtntF+2osYScweocipPrGeONLKU9sngWZ2vnnvw1SBneTa\n"
157 "irxq0Q0SD6Bx9jtxvdf87euk8JzfPhX8jp8GEeAjmLwGR+tnOQrDmczGNmp7YYNN\n"
158 "R+Q7NZVoYWHw5jaoZnNxbouWUXZZxFqDsB/ndCKWtsIzRYPuWcqrFcmUN4SVAgMB\n"
159 "AAGjJjAkMA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMA0GCSqG\n"
160 "SIb3DQEBBQUAA4IBAQAIkdDSErzPLPYrVthw4lKjW4tRYelUicMPEHKjQeVUAAS5\n"
161 "y9XTzB4DWISDAFsgtQjqHJj0xCG+vpY0Rmn2FCO/0YpP+YBQkdbJOsiyXCdFy9e4\n"
162 "gGjQ24gw1B+rr84+pkI51y952NYBdoQDeb7diPe+24U94f//DYt/JQ8cJua4alr3\n"
163 "2Pohhh5TxCXXfU2EHt67KyqBSxCSy9m4OkCOGLHL2X5nQIdXVj178mw6DSAwyhwR\n"
164 "n3uJo5MvUEoQTFZJKGSXfab619mIgzEr+YHsIQToqf44VfDMDdM+MFiXQ3a5fLii\n"
165 "hEKQ9DhBPtpHAbhFA4jhCiG9HA8FdEplJ+M4uxNz\n"
166 "-----END CERTIFICATE-----\n",
167
168 /* NTC_TPM_EK_Root_CA_ARSUF_01 */
169 "-----BEGIN CERTIFICATE-----\n"
170 "MIIDWTCCAkGgAwIBAgIJAMklAEG4bgQ6MA0GCSqGSIb3DQEBBQUAMFgxVjAiBgNV\n"
171 "BAMTG05UQyBUUE0gRUsgUm9vdCBDQSBBUlNVRiAwMTAlBgNVBAoTHk51dm90b24g\n"
172 "VGVjaG5vbG9neSBDb3Jwb3JhdGlvbjAJBgNVBAYTAlRXMB4XDTE0MDQwMTE4MzQz\n"
173 "OFoXDTM0MDMyODE4MzQzOFowWDFWMCIGA1UEAxMbTlRDIFRQTSBFSyBSb290IENB\n"
174 "IEFSU1VGIDAxMCUGA1UEChMeTnV2b3RvbiBUZWNobm9sb2d5IENvcnBvcmF0aW9u\n"
175 "MAkGA1UEBhMCVFcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCxcfP\n"
176 "yaNsGhaR28qqisqkrb4Z2OPul7BRNlIEYP8jSFORygyfp4j7bKRyVTTONCUbPq+J\n"
177 "/a4yRcdbEs8dzvzXypQbVUjuC4sOKjPiWLfOhj1Z1yvOn19Xe3Ei4UzMKJm+xpb1\n"
178 "BYR4YfrnuVzL4do/B/lCr2AYs4Fmtn1uzXBp1St8TRJz9HTW1yKJ2ZOqTgW3DX80\n"
179 "6DP//3kIatTuLCZ6Zsdl6fsgMPxJGwrI35ThKBtaUMT93abb/KB/dugvoIgtEi9D\n"
180 "GEC2C0UWsvJEfu0Qi8zoxtYvd9Y2tRlMxMhK75uShXHxRcG+WOGEnm6uVpGphLKg\n"
181 "qxAl1tuFcb94vi7dAgMBAAGjJjAkMA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8E\n"
182 "CDAGAQH/AgEAMA0GCSqGSIb3DQEBBQUAA4IBAQB7epeKy2Sa+9huMzK4PnIpjiaX\n"
183 "QrxPx+E8BVGw6VuQqTcTPQRvPhNpc4VF/6/7MA9qb6vDxWEf40tqNi8e/RPNlRFY\n"
184 "Dh4tQ1Hhl69NrZVYZeXl1cU/ometoAAbz79ugq78iFndJ5rHMQ85GRwtW9i/q0p1\n"
185 "VjJ8dLYJ7aRBDTP3hndc35GmZg3q1UX93WD6mM5KuE+mOdv7MXKMtYSrV+dE/iGM\n"
186 "ASrratJf57P6N8BpegPQaSb6UnElwBpwhRxzW7N9qgjQWIqrxe97CfJk41RvtnKu\n"
187 "SePqlm1PtWkygt9bYaInLZYkcknXTD/7BtzAyyS25HtG/YTvuMtKItCp7Z4n\n"
188 "-----END CERTIFICATE-----\n",
189
190 /* Nuvoton TPM Root CA 1013 */
191 "-----BEGIN CERTIFICATE-----\n"
192 "MIIDkjCCAnqgAwIBAgIISN0JfIK6vE0wDQYJKoZIhvcNAQEFBQAwVTFTMB8GA1UE\n"
193 "AxMYTnV2b3RvbiBUUE0gUm9vdCBDQSAxMDEzMCUGA1UEChMeTnV2b3RvbiBUZWNo\n"
194 "bm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwHhcNMTUwNTExMDg0MzI1WhcN\n"
195 "MzUwNTA3MDg0MzI1WjBVMVMwHwYDVQQDExhOdXZvdG9uIFRQTSBSb290IENBIDEw\n"
196 "MTMwJQYDVQQKEx5OdXZvdG9uIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24wCQYDVQQG\n"
197 "EwJUVzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDAta6EZBlhF1MC\n"
198 "Z9GeMXqw8puwZEDI3qR/rwGhEUj2oqhFY/K9zUk2YQCkC6X5lrr/lbWfvZtUGMFC\n"
199 "P4VQlt+bGPTOladGg6zJ/7a6yCd9MqkZbw92niDNhWcXsiB7SRyHYdr/He8tNOoD\n"
200 "mVdNFXxknP8QH3soBPahxckqtrhhk+24Iran04jOAc0959VnP8H0Jyg4BjehIQjj\n"
201 "BGGK+bJWZXHYRFlDj4dRW+epChdOqTpWOulf5GOvwNm3sv4ojU2fJ8cA5TznX81z\n"
202 "+Se6hmw/RF8rUGjf1uiKbsxnbIf3An01mZYgD98FXEHAWAW92vAJUuEQJVBlTest\n"
203 "1YmsaT0CAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8C\n"
204 "AQAwHwYDVR0jBBgwFoAUoNc3KQ4WzyrivucQDPVrLwTF8EMwHQYDVR0OBBYEFKDX\n"
205 "NykOFs8q4r7nEAz1ay8ExfBDMA0GCSqGSIb3DQEBBQUAA4IBAQCOXMzQYz3vr9tg\n"
206 "SiFr6qha2+Jay+EK0iLjSKvNzcTv5yaO8I6pb7tdocvze8394PtM42d2OTOM99lJ\n"
207 "bZogquaJ6fLHMwzO7UEGndtm6YMp6APXk4ecRqUDLqofIWL6PQUVwSEYlAC6RM9k\n"
208 "n4MJqckIxsc6iC38lsjyn4ut8o/E3fIo8UzYDl2P+KK1VkjDcmmgNf6seHmBsOYC\n"
209 "vOc4xYpq0yWuZFfxeyC4wC4mOAKLZX2yLMYrYBmnDd60nc0hgI1/TKb1H/Ew2P7R\n"
210 "UxEDMGe8e3A9YR4M/09FLn8cTTjq7hflRlcqiarpPo6+9Z3dqzmqTQxvVQ/DIVqE\n"
211 "3r3WOnnr\n"
212 "-----END CERTIFICATE-----\n",
213
214 /* Nuvoton TPM Root CA 1014 */
215 "-----BEGIN CERTIFICATE-----\n"
216 "MIIDkjCCAnqgAwIBAgIIbXSeZ/22esUwDQYJKoZIhvcNAQEFBQAwVTFTMB8GA1UE\n"
217 "AxMYTnV2b3RvbiBUUE0gUm9vdCBDQSAxMDE0MCUGA1UEChMeTnV2b3RvbiBUZWNo\n"
218 "bm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwHhcNMTcwODIxMTEwMzM2WhcN\n"
219 "MzcwODE3MTEwMzM2WjBVMVMwHwYDVQQDExhOdXZvdG9uIFRQTSBSb290IENBIDEw\n"
220 "MTQwJQYDVQQKEx5OdXZvdG9uIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24wCQYDVQQG\n"
221 "EwJUVzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMd3U7eh2gF2h7LE\n"
222 "b6GZTP/TtWq3cK8QMFuGI6PrwXjwGm1JfG6vF+1u/z4tJbc8znK8Kc/XTZ1yqoZW\n"
223 "sz7dXP20eltU0fuB7qwa2yJOqbl6hZ6nAD+eOuteSUQ8AnEuFH2XqqN++pj9DJXS\n"
224 "zDpvHqP1J6PnpNi6gxVas6PBFrRZuYGOxJwG2miyObHK1/kKrkuE7/yh+ju1j0Rw\n"
225 "9DXhvmEelrztPOkm4TkLxkTQSL7jj+EWimpmGP8Wo+B/2FdVpJZdoFUa2v5GldK8\n"
226 "VBdkacDaSqQ0iX1tP2oI93Jyx1xu9JDqjThrtu+FFIlHFJLw2N91fSCmsJukUiCI\n"
227 "9PPakQUCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8C\n"
228 "AQAwHwYDVR0jBBgwFoAUqdlH8/mBcu623MXtYJoA3nwGnLAwHQYDVR0OBBYEFKnZ\n"
229 "R/P5gXLuttzF7WCaAN58BpywMA0GCSqGSIb3DQEBBQUAA4IBAQBCVMox72wTII5D\n"
230 "fjznST8qr61I6ctKouW401l/x5EA2gBctsx5gl3tuq9EArM2TuA9F+leyJ8r/Tdu\n"
231 "do8TgM4iCVl+FthXlrkPVemd1le63v0Emaxd/8Vca9ZZbrLlC6WNiUj/nGyYThPK\n"
232 "3XIHQN0+OoNdXQM5IxUYylgiA3udzcLCS0oL8uWhpa5YX2ad2UB3xKiz3maI7sXF\n"
233 "Dk5ds45MimR0p/dd+4y2tnAB1f/neR9/CqE58GQcFDY10mpNUa3rBqcUnHcJCfvb\n"
234 "i5TX/clYY/wsVDPwjA5u3k7KSOip7FR33EfIPubE/nMeVqDTiZt+RBJ81xskBO0+\n"
235 "x7bKAs+x\n"
236 "-----END CERTIFICATE-----\n",
237
238 /* Nuvoton TPM Root CA 1110 */
239 "-----BEGIN CERTIFICATE-----\n"
240 "MIICBjCCAaygAwIBAgIIEDiqn2SaqGMwCgYIKoZIzj0EAwIwVTFTMB8GA1UEAxMY\n"
241 "TnV2b3RvbiBUUE0gUm9vdCBDQSAxMTEwMCUGA1UEChMeTnV2b3RvbiBUZWNobm9s\n"
242 "b2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwHhcNMTUwNTExMDg0MzMzWhcNMzUw\n"
243 "NTA3MDg0MzMzWjBVMVMwHwYDVQQDExhOdXZvdG9uIFRQTSBSb290IENBIDExMTAw\n"
244 "JQYDVQQKEx5OdXZvdG9uIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24wCQYDVQQGEwJU\n"
245 "VzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDVkEOpuyhuviaDH6xQj3faaV2Z4\n"
246 "FvXSdwUkTiB1JjPDgv1PU0SFYtEE1W9VmI1GcOn5FAUi2/QM36DPhmPTd+qjZjBk\n"
247 "MA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQV\n"
248 "kdS26vmNAQSGS2kDpI3QAmB30zAfBgNVHSMEGDAWgBQVkdS26vmNAQSGS2kDpI3Q\n"
249 "AmB30zAKBggqhkjOPQQDAgNIADBFAiEAlfxysfHDcxYDed5dmRbvHPKHLEEq9Y9P\n"
250 "wAxoKqH7Q5kCIGfsxiLr2j9nJ9jELwXz0/VWN9PhUNdM3qmsx2JEne6p\n"
251 "-----END CERTIFICATE-----\n",
252
253 /* Nuvoton TPM Root CA 1111 */
254 "-----BEGIN CERTIFICATE-----\n"
255 "MIICBzCCAa2gAwIBAgIJAN/u3L0l8osZMAoGCCqGSM49BAMCMFUxUzAfBgNVBAMT\n"
256 "GE51dm90b24gVFBNIFJvb3QgQ0EgMTExMTAlBgNVBAoTHk51dm90b24gVGVjaG5v\n"
257 "bG9neSBDb3Jwb3JhdGlvbjAJBgNVBAYTAlRXMB4XDTE3MDgyMTAzMzI1M1oXDTM3\n"
258 "MDgxNzAzMzI1M1owVTFTMB8GA1UEAxMYTnV2b3RvbiBUUE0gUm9vdCBDQSAxMTEx\n"
259 "MCUGA1UEChMeTnV2b3RvbiBUZWNobm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMC\n"
260 "VFcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATRcgnHcQk99FFMQ+9UVVFzf64J\n"
261 "1jnhxpGAdZEHRleZfkfTYGHsdr3L9FLdGVUb+BA2cim30ovuPDZOGOUKPraLo2Yw\n"
262 "ZDAOBgNVHQ8BAf8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU\n"
263 "iC8Ee4cSHPmIXzEWC8e7VYavRxswHwYDVR0jBBgwFoAUiC8Ee4cSHPmIXzEWC8e7\n"
264 "VYavRxswCgYIKoZIzj0EAwIDSAAwRQIhANrKhBfLXyHCznBRtWRBmTbfYJR9mCl1\n"
265 "2N/xZkcohRZIAiBDufnmhZWCbX4pibbzAOgcxjsc5+qmpAovxW9ipWJEsA==\n"
266 "-----END CERTIFICATE-----\n",
267
268 /* Nuvoton TPM Root CA 2010 */
269 "-----BEGIN CERTIFICATE-----\n"
270 "MIIDkjCCAnqgAwIBAgIIWAnP9p2CIZcwDQYJKoZIhvcNAQEFBQAwVTFTMB8GA1UE\n"
271 "AxMYTnV2b3RvbiBUUE0gUm9vdCBDQSAyMDEwMCUGA1UEChMeTnV2b3RvbiBUZWNo\n"
272 "bm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwHhcNMTUwNDIzMDY1OTE5WhcN\n"
273 "MzUwNDE5MDY1OTE5WjBVMVMwHwYDVQQDExhOdXZvdG9uIFRQTSBSb290IENBIDIw\n"
274 "MTAwJQYDVQQKEx5OdXZvdG9uIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24wCQYDVQQG\n"
275 "EwJUVzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKcE9saVURE582ny\n"
276 "dHsZO7+3xmdMFbOPCdplBda/EJg9cg7n6bZ79Qv7hyymN5qE23SOPNFvm8SAdmCJ\n"
277 "ybmTnk1y+SyiDw5gUpckbXsRYAetTwqtdfBkF4TkFoRJDIraQC8miTdYqXMXfWTo\n"
278 "bhHXf/oV953laOCO/SRlqXzAWzm5d8PwixUBLZTnvcgxM+pXwv6JY6wgXpv55fY1\n"
279 "D3M1hyiNALib+rg0LwazalU0DOryAAIqFzMgkR2IaefkAmpmQ1xpfMJsK+BMixcI\n"
280 "XUCzSGGKKdkc3WUDye/vsyXYQ5zoYuLt3xb7BEZxes31lqbs1gniNz4oD5ptmrS4\n"
281 "8V7Rz/kCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8C\n"
282 "AQAwHwYDVR0jBBgwFoAUCDAPQ6j0uMjmJKT3Bgz1nnRQFecwHQYDVR0OBBYEFAgw\n"
283 "D0Oo9LjI5iSk9wYM9Z50UBXnMA0GCSqGSIb3DQEBBQUAA4IBAQAE0pMnjz5o3QUd\n"
284 "S3lLQn3+vXkS2xc1EmPxcVFxjPbrJDtnNRMWwglC8zo70VgWu/+ulwzy783zJSiT\n"
285 "nkWPeuszqp3xOtCPWDE4D2sxVbWH3pvel2tgZJv0KJsJH93QE53WbHUwSn2JjHNH\n"
286 "UJiBpq0genUxGD+zBI3NGDGB1iti66aJfCdjn8C0G0gTmQ8jFpZ6AsX1GSvPYeU6\n"
287 "EqN9ynIEYUVcRKwoHQaSmqDd7HVp97fwD+mkOfFYByLVUqC09rNFW81Va4Ze2gw2\n"
288 "HiKz/SVSA5mA/91wfEZSZ6azOgDZNQlbgBo27mZFJ5mR7iJbWgtD+vO4+wRZK8Bc\n"
289 "8yWxV8ri\n"
290 "-----END CERTIFICATE-----\n",
291
292 /* Nuvoton TPM Root CA 2011 */
293 "-----BEGIN CERTIFICATE-----\n"
294 "MIIDkjCCAnqgAwIBAgIIGCgneR7Ow/EwDQYJKoZIhvcNAQEFBQAwVTFTMB8GA1UE\n"
295 "AxMYTnV2b3RvbiBUUE0gUm9vdCBDQSAyMDExMCUGA1UEChMeTnV2b3RvbiBUZWNo\n"
296 "bm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwHhcNMTcwOTExMDcxMDEyWhcN\n"
297 "MzcwOTA3MDcxMDEyWjBVMVMwHwYDVQQDExhOdXZvdG9uIFRQTSBSb290IENBIDIw\n"
298 "MTEwJQYDVQQKEx5OdXZvdG9uIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24wCQYDVQQG\n"
299 "EwJUVzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAfy7Iu3eTXYdXe\n"
300 "WWc8ZPHb1ekofnHWY4Y6QD+z256j2rXTGmk5bA1Y6nCsYtBqUV4B2gfPAaZXunMD\n"
301 "k3KDEBaI8Fkd7BTXbWHrfgxZstGHlWzVqi1r2Jj31MdDMz0NRovWXJwgG5N9tgs5\n"
302 "KEeQ0Kk2ock1Vdn/jIqx3xY9vBMZm97N11m/WtZ5U2NyxbfqIIloIhxuvoPZRzx8\n"
303 "c6MmI77MtM2ylm+2nbXf1DtbEKXQYuGnvM3Ib9K5f2+PTjNi/nWGAcCgLo89BNSB\n"
304 "LdG9GxK1hO9QXYcCkAWsEWUD+8DM1v+zAl2cnrtj4iu48sU5i6hVO0CTtCP0yOkf\n"
305 "VdVfNVsCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8C\n"
306 "AQAwHwYDVR0jBBgwFoAUpSy2R+CQm9ouf32RP2LYixOJ4sYwHQYDVR0OBBYEFKUs\n"
307 "tkfgkJvaLn99kT9i2IsTieLGMA0GCSqGSIb3DQEBBQUAA4IBAQAUwrhniUs4CLgb\n"
308 "UIFPslx3aly8M2P8Vn0GR+EcE0GklFa26WOT+YZxacUP3rMGteZGCtbFggYcM94n\n"
309 "pog7FBnnDR1ySHbHOY0kWBO75ePVBmytqpPeZX8E5202sRgagnojl59bPj1tqhlH\n"
310 "vwj6Xj6/XAFZDo0Or2GhCC5NzRbXmc6wB0zIjTlhPwVXQ+ikKBqdt3/HKCB4i3Sv\n"
311 "7Dxyy/N4aPg/s6MJxgmUjtGxRyjU6RVgrzqVN/0Csv8L75g2SvzgXnqrqcpk82XT\n"
312 "CnJgflpaCfV2SC5MGWHEjmj1tghC133JcEMQlsodWRm+0x7E/fsHvJNj4A0nh9K3\n"
313 "H3TryFJ7\n"
314 "-----END CERTIFICATE-----\n",
315
316 /* Nuvoton TPM Root CA 2110 */
317 "-----BEGIN CERTIFICATE-----\n"
318 "MIICBjCCAaygAwIBAgIIP5MvnZk8FrswCgYIKoZIzj0EAwIwVTFTMB8GA1UEAxMY\n"
319 "TnV2b3RvbiBUUE0gUm9vdCBDQSAyMTEwMCUGA1UEChMeTnV2b3RvbiBUZWNobm9s\n"
320 "b2d5IENvcnBvcmF0aW9uMAkGA1UEBhMCVFcwHhcNMTUxMDE5MDQzMjAwWhcNMzUx\n"
321 "MDE1MDQzMjAwWjBVMVMwHwYDVQQDExhOdXZvdG9uIFRQTSBSb290IENBIDIxMTAw\n"
322 "JQYDVQQKEx5OdXZvdG9uIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24wCQYDVQQGEwJU\n"
323 "VzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPv9uK2BNm8/nmIyNsc2/aKHV0WR\n"
324 "ptzge3jKAIgUMosQIokl4LE3iopXWD3Hruxjf9vkLMDJrTeK3hWh2ySS4ySjZjBk\n"
325 "MA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSf\n"
326 "u3mqD1JieL7RUJKacXHpajW+9zAfBgNVHSMEGDAWgBSfu3mqD1JieL7RUJKacXHp\n"
327 "ajW+9zAKBggqhkjOPQQDAgNIADBFAiEA/jiywhOKpiMOUnTfDmXsXfDFokhKVNTX\n"
328 "B6Xtqm7J8L4CICjT3/Y+rrSnf8zrBXqWeHDh8Wi41+w2ppq6Ev9orZFI\n"
329 "-----END CERTIFICATE-----\n",
330
331 /* Nuvoton TPM Root CA 2111 */
332 "-----BEGIN CERTIFICATE-----\n"
333 "MIICBzCCAa2gAwIBAgIJAOCIUWvKMfuGMAoGCCqGSM49BAMCMFUxUzAfBgNVBAMT\n"
334 "GE51dm90b24gVFBNIFJvb3QgQ0EgMjExMTAlBgNVBAoTHk51dm90b24gVGVjaG5v\n"
335 "bG9neSBDb3Jwb3JhdGlvbjAJBgNVBAYTAlRXMB4XDTE3MDkxMTA3MDk0OVoXDTM3\n"
336 "MDkwNzA3MDk0OVowVTFTMB8GA1UEAxMYTnV2b3RvbiBUUE0gUm9vdCBDQSAyMTEx\n"
337 "MCUGA1UEChMeTnV2b3RvbiBUZWNobm9sb2d5IENvcnBvcmF0aW9uMAkGA1UEBhMC\n"
338 "VFcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATanNywPkE/RICBZ4VjwCymLDts\n"
339 "B7Unv52Oj0HyEsAfc7+vjOl2DP8JbrcozY05s7GFfQqR3vhv4ZdkJMalgOr2o2Yw\n"
340 "ZDAOBgNVHQ8BAf8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU\n"
341 "I/TiKtO+N0pEl3KVSqKDrtdSVy4wHwYDVR0jBBgwFoAUI/TiKtO+N0pEl3KVSqKD\n"
342 "rtdSVy4wCgYIKoZIzj0EAwIDSAAwRQIgXgXs2eVt2U4sCoRf1GLoUTf2ZzYTSsyg\n"
343 "6I5w6hPTLigCIQDLLFlXK1xw1a1D1/idVhdd3a8gkE0FnTJO890WwiQbpg==\n"
344 "-----END CERTIFICATE-----"
345 };
346
347 #endif /* FAPI_CERTIFICATES_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11
12 #include <openssl/evp.h>
13 #include <openssl/aes.h>
14 #include <openssl/rsa.h>
15 #include <openssl/engine.h>
16 #include <openssl/pem.h>
17 #include <openssl/x509v3.h>
18 #include <curl/curl.h>
19 #include <openssl/err.h>
20
21 #include "fapi_certificates.h"
22 #include "fapi_util.h"
23 #include "util/aux_util.h"
24 #include "fapi_crypto.h"
25 #define LOGMODULE fapi
26 #include "util/log.h"
27
28 /** Context to hold temporary values for ifapi_crypto */
29 typedef struct _IFAPI_CRYPTO_CONTEXT {
30 /** The hash engine's context */
31 EVP_MD_CTX *osslContext;
32 /** The currently used hash algorithm */
33 const EVP_MD *osslHashAlgorithm;
34 /** The size of the hash's digest */
35 size_t hashSize;
36 } IFAPI_CRYPTO_CONTEXT;
37
38 /** A singleton crypto engine for hash operations */
39 static ENGINE *engine = NULL;
40
41 /**
42 * Returns the signature scheme that is currently used in the FAPI context.
43 *
44 * @param[in] profile The FAPI profile from which the signing scheme is
45 * retrieved
46 * @param[in] tpmPublic The public key for which the signing key is fetched
47 * from the FAPI
48 * @param[out] signatureScheme The currently used signature scheme
49 *
50 * @retval TSS2_RC_SUCCESS if the signature scheme was successfully fetched
51 * @retval TSS2_FAPI_RC_BAD_REFERENCE if one of the parameters is NULL
52 * @retval TSS2_FAPI_RC_BAD_VALUE if the key type is not TPM2_ALG_RSA or
53 * TPM2_ALG_ECC
54 */
55 TPM2_RC
56 ifapi_get_profile_sig_scheme(
57 const IFAPI_PROFILE *profile,
58 const TPMT_PUBLIC *tpmPublic,
59 TPMT_SIG_SCHEME *signatureScheme)
60 {
61 /* Check for NULL parameters */
62 return_if_null(profile, "profile is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
63 return_if_null(tpmPublic, "tpmPublic is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
64 return_if_null(signatureScheme, "signatureScheme is NULL",
65 TSS2_FAPI_RC_BAD_REFERENCE);
66
67 /* Determine the appropriate signing scheme */
68 if (tpmPublic->type == TPM2_ALG_RSA) {
69 *signatureScheme = profile->rsa_signing_scheme;
70 return TSS2_RC_SUCCESS;
71 } else if (tpmPublic->type == TPM2_ALG_ECC) {
72 *signatureScheme = profile->ecc_signing_scheme;
73 return TSS2_RC_SUCCESS;
74 } else {
75 return_error(TSS2_FAPI_RC_BAD_VALUE, "Invalid key type.");
76 }
77 }
78
79 static const TPM2B_PUBLIC templateRsaSign = {
80 .size = 0,
81 .publicArea = {
82 .type = TPM2_ALG_RSA,
83 .nameAlg = TPM2_ALG_SHA1,
84 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
85 TPMA_OBJECT_SIGN_ENCRYPT |
86 TPMA_OBJECT_RESTRICTED |
87 TPMA_OBJECT_SENSITIVEDATAORIGIN
88 ),
89 .authPolicy = {
90 .size = 0,
91 .buffer = 0,
92 },
93 .parameters.rsaDetail = {
94 .symmetric = {
95 .algorithm = TPM2_ALG_NULL,
96 .keyBits.aes = 128,
97 .mode.aes = TPM2_ALG_CFB,
98 },
99 .scheme = {
100 .scheme = TPM2_ALG_RSAPSS,
101 .details.rsapss.hashAlg = TPM2_ALG_SHA1,
102 },
103 .keyBits = 2048,
104 .exponent = 65537,
105 },
106 .unique.rsa = {
107 .size = 0,
108 .buffer = {},
109 }
110 }
111 };
112
113 /**
114 * A FAPI template for ECC signing keys
115 */
116 static const TPM2B_PUBLIC templateEccSign = {
117 .size = 0,
118 .publicArea = {
119 .type = TPM2_ALG_ECC,
120 .nameAlg = TPM2_ALG_SHA1,
121 .objectAttributes = (
122 TPMA_OBJECT_USERWITHAUTH |
123 TPMA_OBJECT_RESTRICTED |
124 TPMA_OBJECT_SIGN_ENCRYPT |
125 TPMA_OBJECT_SENSITIVEDATAORIGIN
126 ),
127 .authPolicy = {
128 .size = 0,
129 },
130
131 .parameters.eccDetail = {
132 .symmetric = {
133 .algorithm = TPM2_ALG_NULL,
134 .keyBits.aes = 128,
135 .mode.aes = TPM2_ALG_ECB,
136 },
137 .scheme = {
138 .scheme = TPM2_ALG_ECDSA,
139 .details = { .ecdsa = { .hashAlg = TPM2_ALG_SHA256 }},
140 },
141 .curveID = TPM2_ECC_BN_P256,
142 .kdf = { .scheme = TPM2_ALG_NULL, .details = {} }
143 },
144 .unique.ecc = {
145 .x = { .size = 0, .buffer = {} },
146 .y = { .size = 0, .buffer = {} },
147 },
148 },
149 };
150
151 /**
152 * Initializes a FAPI key template for a given signature algorithm.
153 *
154 * @param[in] signatureAlgorithm The signature algorithm to use. Must be
155 * TPM2_ALG_RSA or TPM2_ALG_ECC
156 * @param[out] public The template to initialize
157 *
158 * @retval TSS2_RC_SUCCESS on success
159 * @retval TSS2_FAPI_RC_BAD_REFERENCE if template is NULL
160 * @retval TSS2_FAPI_RC_BAD_VALUE if signatureAlgorithm is not TPM2_ALG_RSA or
161 * TPM2_ALG_ECC
162 */
163 TSS2_RC
164 ifapi_initialize_sign_public(TPM2_ALG_ID signatureAlgorithm,
165 TPM2B_PUBLIC *public) {
166
167 /* Check for NULL parameters */
168 return_if_null(public, "public is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
169
170 /* Initialize the template */
171 if (signatureAlgorithm == TPM2_ALG_RSA) {
172 /* RSA key template */
173 memcpy(public, &templateRsaSign, sizeof(TPM2B_PUBLIC));
174 } else if (signatureAlgorithm == TPM2_ALG_ECC) {
175 /* ECC key template */
176 memcpy(public, &templateEccSign, sizeof(TPM2B_PUBLIC));
177 } else {
178 /* Invalid key type */
179 LOG_ERROR("No suitable template found");
180 return TSS2_FAPI_RC_BAD_VALUE;
181 }
182 return TSS2_RC_SUCCESS;
183 }
184
185 /**
186 * Converts an openSSL BIGNUM into a binary byte buffer using.
187 *
188 * @param[in] bn The BIGNUM to convert
189 * @param[out] bin The binary buffer to which the bignum is converted
190 * @param[in] binSize The size of bin in bytes
191 *
192 * @retval 1 if the conversion was successful
193 * @retval 0 if one of the parameters is NULL
194 */
195 static int
196 ifapi_bn2binpad(const BIGNUM *bn, unsigned char *bin, int binSize)
197 {
198 /* Check for NULL parameters */
199 return_if_null(bn, "bn is NULL", 0);
200 return_if_null(bin, "bin is NULL", 0);
201
202 /* Convert bn */
203 int bnSize = BN_num_bytes(bn);
204 int offset = binSize - bnSize;
205 memset(bin, 0, offset);
206 BN_bn2bin(bn, bin + offset);
207 return 1;
208 }
209
210 /**
211 * Returns the singleton hash engine for the use in ifapi_hash operations. If
212 * it does not yet exist, this function creates it.
213 *
214 * @retval A singleton hash engine
215 */
216 static ENGINE *
217 get_engine()
218 {
219 /* If an engine is present, it is returned */
220 if (engine)
221 return engine;
222 /* Otherwise, engine is created and returned */
223 engine = ENGINE_by_id(NULL);
224 return engine;
225 }
226
227 /**
228 * Returns a suitable openSSL hash algorithm identifier for a given TSS hash
229 * algorithm identifier.
230 *
231 * @param[in] hashAlgorithm The TSS hash algorithm identifier
232 *
233 * @retval An openSSL hash algorithm identifier if one that is suitable to
234 * hashAlgorithm could be found
235 * @retval NULL if no suitable hash algorithm identifier could be found
236 */
237 static const EVP_MD *
238 get_hash_md(TPM2_ALG_ID hashAlgorithm)
239 {
240 switch (hashAlgorithm) {
241 case TPM2_ALG_SHA1:
242 return EVP_sha1();
243 case TPM2_ALG_SHA256:
244 return EVP_sha256();
245 case TPM2_ALG_SHA384:
246 return EVP_sha384();
247 case TPM2_ALG_SHA512:
248 return EVP_sha512();
249 default:
250 return NULL;
251 }
252 }
253
254 /**
255 * Returns a suitable openSSL RSA signature scheme identifiver for a given TSS
256 * RSA signature scheme identifier.
257 *
258 * @param[in] signatureScheme The TSS RSA signature scheme identifier
259 *
260 * @retval RSA_PCKS1_PSS_PADDING if signatureScheme is TPM2_ALG_RSAPSS
261 * @retval RSA_PKCS1_PADDING if signatureScheme is TPM2_ALG_RSASSA
262 * @retval 0 otherwise
263 */
264 static int
265 get_sig_scheme(TPM2_ALG_ID signatureScheme)
266 {
267 switch (signatureScheme) {
268 case TPM2_ALG_RSAPSS:
269 return RSA_PKCS1_PSS_PADDING;
270 case TPM2_ALG_RSASSA:
271 return RSA_PKCS1_PADDING;
272 default:
273 return 0;
274 }
275 }
276
277 /**
278 * Convert a TPM ECDSA signature into a DER formatted byte buffer. This can be
279 * used by TLS libraries.
280 *
281 * @param[in] tpmSignature The signature created by the TPM
282 * @param[out] signature A byte buffer that will hold the DER representation of
283 * the signature (callee allocated)
284 * @param[out] signatureSize The size of signature in bytes. May be NULL
285 *
286 * @retval TSS2_RC_SUCCESS on success
287 * @retval TSS2_FAPI_RC_BAD_REFERENCE if tpmSignature is NULL
288 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
289 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
290 */
291 TSS2_RC
292 ifapi_tpm_ecc_sig_to_der(
293 const TPMT_SIGNATURE *tpmSignature,
294 uint8_t **signature,
295 size_t *signatureSize)
296 {
297 /* Check for NULL parameters */
298 return_if_null(tpmSignature, "tpmSignature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
299
300 ECDSA_SIG *ecdsaSignature = NULL;
301 BIGNUM *bns = NULL, *bnr = NULL;
302 int osslRC;
303 TSS2_RC r;
304 uint8_t *signatureWalking;
305
306 /* Initialize an OpenSSL ECDSA signature which servers as an intermediate
307 * between the TSS ECDSA signature and the DER byte buffer */
308 ecdsaSignature = ECDSA_SIG_new();
309 goto_if_null(ecdsaSignature, "Out of memory", TSS2_FAPI_RC_MEMORY,
310 cleanup);
311
312 bns = BN_bin2bn(&tpmSignature->signature.ecdsa.signatureS.buffer[0],
313 tpmSignature->signature.ecdsa.signatureS.size, NULL);
314 goto_if_null(bns, "Out of memory", TSS2_FAPI_RC_MEMORY, cleanup);
315
316 bnr = BN_bin2bn(&tpmSignature->signature.ecdsa.signatureR.buffer[0],
317 tpmSignature->signature.ecdsa.signatureR.size, NULL);
318 goto_if_null(bnr, "Out of memory", TSS2_FAPI_RC_MEMORY, cleanup);
319
320 #if OPENSSL_VERSION_NUMBER < 0x10100000
321 ecdsaSignature->s = bns;
322 ecdsaSignature->r = bnr;
323 #else /* OPENSSL_VERSION_NUMBER < 0x10100000 */
324 ECDSA_SIG_set0(ecdsaSignature, bnr, bns);
325 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
326
327 osslRC = i2d_ECDSA_SIG(ecdsaSignature, NULL);
328 if (osslRC == -1) {
329 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL error", cleanup);
330 }
331
332 /* Initialize the byte buffer for the DER representation */
333 *signature = malloc(osslRC);
334 signatureWalking = *signature;
335 goto_if_null(*signature, "Out of memory", TSS2_FAPI_RC_MEMORY, cleanup);
336
337 if (signatureSize != NULL) {
338 *signatureSize = osslRC;
339 }
340
341 /* Convert the OpenSSL ECDSA signature to the DER buffer */
342 osslRC = i2d_ECDSA_SIG(ecdsaSignature, &signatureWalking);
343 if (!osslRC) {
344 free(*signature);
345 if (signatureSize != NULL) {
346 *signatureSize = 0;
347 }
348 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL error", cleanup);
349 }
350 r = TSS2_RC_SUCCESS;
351
352 cleanup:
353 if (ecdsaSignature)
354 ECDSA_SIG_free(ecdsaSignature);
355 return r;
356 }
357
358 /**
359 * Converts a public RSA key created by the TPM into one that can be used by
360 * OpenSSL.
361 *
362 * @param[in] tpmPublicKey The public RSA key created by the TPM
363 * @param[out] evpPublicKey The converted public RSA key that can be used by
364 * OpenSSL
365 *
366 * @retval TSS2_RC_SUCCESS on success
367 * @retval TSS2_FAPI_RC_BAD_REFERENCE if one of the parameters is NULL
368 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
369 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
370 */
371 static TSS2_RC
372 ossl_rsa_pub_from_tpm(const TPM2B_PUBLIC *tpmPublicKey, EVP_PKEY *evpPublicKey)
373 {
374 /* Check for NULL parameters */
375 return_if_null(tpmPublicKey, "tpmPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
376 return_if_null(evpPublicKey, "evpPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
377
378 /* Initialize the RSA parameters */
379 TSS2_RC r;
380 RSA *rsa = RSA_new();
381 BIGNUM *e = BN_new();
382 BIGNUM *d = BN_new();
383 BIGNUM *p = BN_new();
384 BIGNUM *q = BN_new();
385 BIGNUM *dmp1 = BN_new();
386 BIGNUM *dmq1 = BN_new();
387 BIGNUM *iqmp = BN_new();
388 BIGNUM *n = BN_bin2bn(tpmPublicKey->publicArea.unique.rsa.buffer,
389 tpmPublicKey->publicArea.unique.rsa.size, NULL);
390
391 if (!n || !e || !d || !p || !q || !dmp1 || !dmq1 || !iqmp || !rsa) {
392 goto_error(r, TSS2_FAPI_RC_MEMORY, "Out of memory", error_cleanup);
393 }
394
395 BN_set_word(d, 0);
396 BN_set_word(p, 0);
397 BN_set_word(q, 0);
398 BN_set_word(dmp1, 0);
399 BN_set_word(dmq1, 0);
400 BN_set_word(iqmp, 0);
401 uint32_t exp;
402 if (tpmPublicKey->publicArea.parameters.rsaDetail.exponent == 0)
403 exp = 65537;
404 else
405 exp = tpmPublicKey->publicArea.parameters.rsaDetail.exponent;
406 if (1 != BN_set_word(e, exp)) {
407 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
408 "Could not set exponent.", error_cleanup);
409 }
410
411 #if OPENSSL_VERSION_NUMBER < 0x10100000
412 rsa->e = e;
413 rsa->n = n;
414 rsa->d = d;
415 rsa->p = p;
416 rsa->q = q;
417 rsa->dmp1 = dmp1;
418 rsa->dmq1 = dmq1;
419 rsa->iqmp = iqmp;
420 #else /* OPENSSL_VERSION_NUMBER < 0x10100000 */
421 RSA_set0_key(rsa, n, e, d);
422 RSA_set0_factors(rsa, p, q);
423 RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
424 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
425
426 /* Assign the parameters to the key */
427 if (!EVP_PKEY_assign_RSA(evpPublicKey, rsa)) {
428 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Assign rsa key",
429 error_cleanup);
430 }
431 return TSS2_RC_SUCCESS;
432
433 error_cleanup:
434 OSSL_FREE(rsa, RSA);
435 OSSL_FREE(e, BN);
436 OSSL_FREE(n, BN);
437 OSSL_FREE(d, BN);
438 OSSL_FREE(p, BN);
439 OSSL_FREE(q, BN);
440 OSSL_FREE(dmp1, BN);
441 OSSL_FREE(dmq1, BN);
442 OSSL_FREE(iqmp, BN);
443 return r;
444 }
445
446 /**
447 * Converts a public ECC key created by the TPM into one that can be used by
448 * OpenSSL.
449 *
450 * @param[in] tpmPublicKey The public ECC key created by the TPM
451 * @param[out] evpPublicKey The converted public ECC key that can be used by
452 * OpenSSL
453 *
454 * @retval TSS2_RC_SUCCESS on success
455 * @retval TSS2_FAPI_RC_BAD_REFERENCE if one of the parameters is NULL
456 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
457 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
458 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
459 * the function.
460 */
461 static TSS2_RC
462 ossl_ecc_pub_from_tpm(const TPM2B_PUBLIC *tpmPublicKey, EVP_PKEY *evpPublicKey)
463 {
464 /* Check for NULL parameters */
465 return_if_null(tpmPublicKey, "tpmPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
466 return_if_null(evpPublicKey, "evpPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
467
468 TSS2_RC r;
469 EC_GROUP *ecgroup = NULL;
470 int curveId;
471 BIGNUM *x = NULL, *y = NULL;
472 EC_KEY *ecKey = EC_KEY_new();
473 return_if_null(ecKey, "Out of memory.", TSS2_FAPI_RC_MEMORY);
474
475 /* Find the curve of the ECC key */
476 switch (tpmPublicKey->publicArea.parameters.eccDetail.curveID) {
477 case TPM2_ECC_NIST_P192:
478 curveId = NID_X9_62_prime192v1;
479 break;
480 case TPM2_ECC_NIST_P224:
481 curveId = NID_secp224r1;
482 break;
483 case TPM2_ECC_NIST_P256:
484 curveId = NID_X9_62_prime256v1;
485 break;
486 case TPM2_ECC_NIST_P384:
487 curveId = NID_secp384r1;
488 break;
489 case TPM2_ECC_NIST_P521:
490 curveId = NID_secp521r1;
491 break;
492 default:
493 return_error(TSS2_FAPI_RC_BAD_VALUE,
494 "ECC curve not implemented.");
495 }
496
497 /* Initialize the OpenSSL ECC key with its group */
498 ecgroup = EC_GROUP_new_by_curve_name(curveId);
499 goto_if_null(ecgroup, "new EC group.", TSS2_FAPI_RC_GENERAL_FAILURE,
500 error_cleanup);
501
502 if (!EC_KEY_set_group(ecKey, ecgroup)) {
503 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EC_KEY_set_group",
504 error_cleanup);
505 }
506 EC_GROUP_free(ecgroup);
507
508 /* Set the ECC parameters in the OpenSSL key */
509 x = BN_bin2bn(tpmPublicKey->publicArea.unique.ecc.x.buffer,
510 tpmPublicKey->publicArea.unique.ecc.x.size, NULL);
511
512 y = BN_bin2bn(tpmPublicKey->publicArea.unique.ecc.y.buffer,
513 tpmPublicKey->publicArea.unique.ecc.y.size, NULL);
514
515 if (!x || !y) {
516 goto_error(r, TSS2_FAPI_RC_MEMORY, "Out of memory", error_cleanup);
517 }
518
519 if (!EC_KEY_set_public_key_affine_coordinates(ecKey, x, y)) {
520 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
521 "EC_KEY_set_public_key_affine_coordinates", error_cleanup);
522 }
523
524 if (!EVP_PKEY_assign_EC_KEY(evpPublicKey, ecKey)) {
525 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Assign ecc key",
526 error_cleanup);
527 }
528 /* Needed for older OSSL versions. */
529 EC_KEY_set_asn1_flag(ecKey, OPENSSL_EC_NAMED_CURVE);
530 OSSL_FREE(y, BN);
531 OSSL_FREE(x, BN);
532 return TSS2_RC_SUCCESS;
533
534 error_cleanup:
535 OSSL_FREE(y, BN);
536 OSSL_FREE(x, BN);
537 OSSL_FREE(ecKey, EC_KEY);
538 return r;
539 }
540
541 /**
542 * Convert a TPM public key into a PEM formatted byte buffer. This can be
543 * used by TLS libraries.
544 *
545 * @param[in] tpmPublicKey The public key created by the TPM
546 * @param[out] pemKey A byte buffer that will hold the PEM representation of
547 * the public key (callee allocated)
548 * @param[out] pemKeySize The size of pemKey in bytes
549 *
550 * @retval TSS2_RC_SUCCESS on success
551 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
552 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
553 * @retval TSS2_FAPI_BAD_REFERENCE if tpmPublicKey or pemKeySize are NULL
554 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
555 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
556 * the function.
557 */
558 TSS2_RC
559 ifapi_pub_pem_key_from_tpm(
560 const TPM2B_PUBLIC *tpmPublicKey,
561 char **pemKey,
562 int *pemKeySize)
563 {
564 /* Check for NULL parameters */
565 return_if_null(tpmPublicKey, "tpmPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
566 return_if_null(pemKeySize, "pemKeySize is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
567
568 EVP_PKEY *evpPublicKey = NULL;
569 BIO *bio = NULL;
570 TSS2_RC r = TPM2_RC_SUCCESS;
571
572 evpPublicKey = EVP_PKEY_new();
573 goto_if_null2(evpPublicKey, "Out of memory.", r, TSS2_FAPI_RC_MEMORY, cleanup);
574
575 /* Memory IO will be used for OSSL key conversion */
576 bio = BIO_new(BIO_s_mem());
577 goto_if_null2(evpPublicKey, "Out of memory.", r, TSS2_FAPI_RC_MEMORY, cleanup);
578
579 if (tpmPublicKey->publicArea.type == TPM2_ALG_RSA) {
580 r = ossl_rsa_pub_from_tpm(tpmPublicKey, evpPublicKey);
581 } else if (tpmPublicKey->publicArea.type == TPM2_ALG_ECC)
582 r = ossl_ecc_pub_from_tpm(tpmPublicKey, evpPublicKey);
583 else {
584 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid alg id.", cleanup);
585 }
586 goto_if_error(r, "Get ossl public key.", cleanup);
587
588 if (!PEM_write_bio_PUBKEY(bio, evpPublicKey)) {
589 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "PEM_write_bio_PUBKEY",
590 cleanup);
591 }
592
593 /* Determine the size of the data written */
594 *pemKeySize = BIO_get_mem_data(bio, pemKey);
595 *pemKey = malloc(*pemKeySize+1);
596 goto_if_null(*pemKey, "Out of memory.", TSS2_FAPI_RC_MEMORY,
597 cleanup);
598 memset(*pemKey, 0, *pemKeySize + 1);
599
600 /* Get the byte buffer written to the BIO object */
601 int readSize = BIO_read(bio, *pemKey, *pemKeySize);
602 if (readSize != *pemKeySize) {
603 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid BIO_read",
604 cleanup);
605 }
606
607 cleanup:
608 EVP_PKEY_free(evpPublicKey);
609 BIO_free(bio);
610 return r;
611 }
612
613 /** Converts an ECDSA signature from a DER encoded byte buffer into the
614 * TPM format. It can then be verified by the TPM.
615 *
616 * @param[in] signature A DER encoded byte buffer holding the signature
617 * @param[in] signatureSize The size of signature in bytes
618 * @param[in] keySize The size of the verification key
619 * @param[in] hashAlgorithm The TSS identifier of the hash algorithm to use
620 * @param[out] tpmSignature The signature in the TPM format
621 *
622 * @retval TSS2_RC_SUCCESS on success
623 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
624 * @retval TSS2_FAPI_RC_BAD_REFERENCE if signature or tpmSignature is NULL
625 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
626 */
627 static TSS2_RC
628 ifapi_ecc_der_sig_to_tpm(
629 const unsigned char *signature,
630 size_t signatureSize,
631 int keySize,
632 TPMI_ALG_HASH hashAlgorithm,
633 TPMT_SIGNATURE *tpmSignature)
634 {
635 /* Check for NULL parameters */
636 return_if_null(signature, "signature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
637 return_if_null(tpmSignature, "tpmSignature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
638
639 /* Initialize the ECDSA signature components */
640 ECDSA_SIG *ecdsaSignature = NULL;
641 #if OPENSSL_VERSION_NUMBER < 0x10100000
642 BIGNUM *bnr;
643 BIGNUM *bns;
644 #else /* OPENSSL_VERSION_NUMBER < 0x10100000 */
645 const BIGNUM *bnr;
646 const BIGNUM *bns;
647 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
648
649 d2i_ECDSA_SIG(&ecdsaSignature, &signature, signatureSize);
650 return_if_null(ecdsaSignature, "Invalid DER signature",
651 TSS2_FAPI_RC_GENERAL_FAILURE);
652
653 #if OPENSSL_VERSION_NUMBER < 0x10100000
654 bns = ecdsaSignature->s;
655 bnr = ecdsaSignature->r;
656 #else /* OPENSSL_VERSION_NUMBER < 0x10100000 */
657 ECDSA_SIG_get0(ecdsaSignature, &bnr, &bns);
658 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
659
660 /* Writing them to the TPM format signature */
661 tpmSignature->signature.ecdsa.hash = hashAlgorithm;
662 tpmSignature->sigAlg = TPM2_ALG_ECDSA; /**< only ECDSA is used by FAPI */
663 ifapi_bn2binpad(bnr, &tpmSignature->signature.ecdsa.signatureR.buffer[0],
664 keySize);
665 tpmSignature->signature.ecdsa.signatureR.size = keySize;
666 ifapi_bn2binpad(bns, &tpmSignature->signature.ecdsa.signatureS.buffer[0],
667 keySize);
668 tpmSignature->signature.ecdsa.signatureS.size = keySize;
669 OSSL_FREE(ecdsaSignature, ECDSA_SIG);
670 //OSSL_FREE(bnr, BN);
671 //OSSL_FREE(bns, BN);
672 return TSS2_RC_SUCCESS;
673 }
674
675 /** Convert signature from DER to TPM format.
676 *
677 * The signature in DER format is converted to TPM format to
678 * enable verification by the TPM.
679 *
680 * @param[in] tpmPublic The public information of the signature key
681 * @param[in] signature A byte buffer holding the DER encoded signature
682 * @param[in] signatureSize The size of signature in bytes
683 * @param[in] hashAlgorithm The TSS identifier for the hash algorithm used
684 * to compute the digest
685 * @param[out] tpmSignature The signature in TPM format
686 *
687 * @retval TSS2_RC_SUCCESS on success
688 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
689 * @retval TSS2_FAPI_RC_BAD_REFERENCE if tpmPublic, signature or tpmSignature is NULL
690 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
691 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
692 * the function.
693 */
694 TSS2_RC
695 ifapi_der_sig_to_tpm(
696 const TPMT_PUBLIC *tpmPublic,
697 const unsigned char *signature,
698 size_t signatureSize,
699 TPMI_ALG_HASH hashAlgorithm,
700 TPMT_SIGNATURE *tpmSignature)
701 {
702 /* Check for NULL parameters */
703 return_if_null(tpmPublic, "tpmPublic is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
704 return_if_null(signature, "signature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
705 return_if_null(tpmSignature, "tpmSignature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
706
707 /* Convert the signature */
708 if (tpmPublic->type == TPM2_ALG_RSA) {
709 if (tpmPublic->parameters.rsaDetail.scheme.scheme == TPM2_ALG_RSAPSS) {
710 tpmSignature->sigAlg = TPM2_ALG_RSAPSS;
711 tpmSignature->signature.rsapss.hash = hashAlgorithm;
712 tpmSignature->signature.rsapss.sig.size = signatureSize;
713 memcpy(&tpmSignature->signature.rsapss.sig.buffer[0], signature,
714 signatureSize);
715 } else if (tpmPublic->parameters.rsaDetail.scheme.scheme == TPM2_ALG_RSASSA) {
716 tpmSignature->sigAlg = TPM2_ALG_RSASSA;
717 tpmSignature->signature.rsassa.hash = hashAlgorithm;
718 tpmSignature->signature.rsassa.sig.size = signatureSize;
719 memcpy(&tpmSignature->signature.rsassa.sig.buffer[0], signature,
720 signatureSize);
721 } else {
722 return_error(TSS2_FAPI_RC_BAD_VALUE, "Invalid RSA scheme.");
723
724 }
725 } else if (tpmPublic->type == TPM2_ALG_ECC) {
726 return ifapi_ecc_der_sig_to_tpm(signature, signatureSize,
727 tpmPublic->unique.ecc.x.size, hashAlgorithm,
728 tpmSignature);
729 } else {
730 return_error(TSS2_FAPI_RC_BAD_VALUE, "Invalid key tpye.");
731 }
732 return TSS2_RC_SUCCESS;
733 }
734
735 /**
736 * Size of the table with the possible padding schemes
737 */
738 #define N_PADDING 2
739
740 /**
741 * Table with possible padding schemes to guess the one appropriate for
742 * for RSA signature verification
743 */
744 static const int rsaPadding[N_PADDING] = { RSA_PKCS1_PADDING, RSA_PKCS1_PSS_PADDING };
745
746 /**
747 * Verifies an RSA signature given as a binary byte buffer.
748 *
749 * @param[in] publicKey The public key with which the signature is to be
750 * verified
751 * @param[in] signature A byte buffer holding the signature to verify
752 * @param[in] signatureSize The size of signature in bytes
753 * @param[in] digest The digest of the signature to verify
754 * @param[in] digestSize The size of digest in bytes. Required to determine the
755 * hash algorithm
756 *
757 * @retval TSS2_RC_SUCCESS on success
758 * @retval TSS2_FAPI_RC_BAD_REFERENCE if publicKey, signature or digest is NULL
759 * @retval TSS2_FAPI_RC_BAD_VALUE if no hash algorithm that matches digestSize
760 * could be found
761 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
762 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the signature could not
763 * be verified
764 */
765 static TSS2_RC
766 rsa_verify_signature(
767 EVP_PKEY *publicKey,
768 const uint8_t *signature,
769 size_t signatureSize,
770 const uint8_t *digest,
771 size_t digestSize)
772 {
773 /* Check for NULL parameters */
774 return_if_null(publicKey, "publicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
775 return_if_null(signature, "signature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
776 return_if_null(digest, "digest is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
777
778 TSS2_RC r;
779 const EVP_MD *mdType;
780 EVP_PKEY_CTX *ctx = NULL;
781
782 /* The hash algorithm of the signature is determined by the digest length */
783 switch (digestSize) {
784 case TPM2_SHA1_DIGEST_SIZE:
785 mdType = EVP_sha1();
786 break;
787 case TPM2_SHA256_DIGEST_SIZE:
788 mdType = EVP_sha256();
789 break;
790 case TPM2_SHA384_DIGEST_SIZE:
791 mdType = EVP_sha384();
792 break;
793 case TPM2_SHA512_DIGEST_SIZE:
794 mdType = EVP_sha512();
795 break;
796 default:
797 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid digest size", cleanup);
798 }
799
800 /* Try all possible padding schemes for verification */
801 for (int i = 0; i < N_PADDING; i++) {
802 ctx = EVP_PKEY_CTX_new(publicKey, NULL);
803 if (!ctx) {
804 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Get pkey context.",
805 cleanup);
806 }
807 if (EVP_PKEY_verify_init(ctx) <= 0) {
808 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Verify init.",
809 cleanup);
810 }
811 if (EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding[i]) <= 0) {
812 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
813 "EVP_PKEY_CTX_set_rsa_padding", cleanup);
814 }
815 if (EVP_PKEY_CTX_set_signature_md(ctx, mdType) <= 0) {
816 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
817 "Verify set signature md.", cleanup);
818 }
819 if (1 != EVP_PKEY_verify(ctx, signature, signatureSize, digest, digestSize)) {
820 /* padding scheme was not appropriate, next should be tried */
821 EVP_PKEY_CTX_free(ctx);
822 } else {
823 /* Verification with selected padding scheme was successful */
824 r = TSS2_RC_SUCCESS;
825 goto cleanup;
826 }
827 }
828 /* Verification was not successful with one of the possible padding schemes */
829 r = TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED;
830
831 cleanup:
832 EVP_PKEY_CTX_free(ctx);
833 return r;
834 }
835
836 /**
837 * Verifies an ECDSA signature given as a binary byte buffer.
838 *
839 * @param[in] publicKey The public key with which the signature is to be
840 * verified
841 * @param[in] signature A byte buffer holding the signature to verify
842 * @param[in] signatureSize The size of signature in bytes
843 * @param[in] digest The digest of the signature to verify
844 * @param[in] digestSize The size of digest in bytes. Required to determine the
845 * hash algorithm
846 *
847 * @retval TSS2_RC_SUCCESS on success
848 * @retval TSS2_FAPI_RC_BAD_REFERENCE if publicKey, signature or digest is NULL
849 * @retval TSS2_FAPI_RC_BAD_VALUE if no hash algorithm that matches digestSize
850 * could be found
851 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
852 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the signature could not
853 * be verified
854 */
855 static TSS2_RC
856 ecdsa_verify_signature(
857 EVP_PKEY *publicKey,
858 const uint8_t *signature,
859 size_t signatureSize,
860 const uint8_t *digest,
861 size_t digestSize)
862 {
863 /* Check for NULL parameters */
864 return_if_null(publicKey, "publicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
865 return_if_null(signature, "signature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
866 return_if_null(digest, "digest is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
867
868 TSS2_RC r = TSS2_RC_SUCCESS;
869 EC_KEY *eccKey = NULL;
870
871 eccKey = EVP_PKEY_get1_EC_KEY(publicKey);
872
873 /* Try to verify the signature using ECDSA, note that param 0 is unused */
874 int rc = ECDSA_verify(0, digest, digestSize, signature, signatureSize, eccKey);
875 if (rc == 0) {
876 goto_error(r, TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED,
877 "ECDSA signature verification failed.", error_cleanup);
878 } else if (rc < 0) {
879 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
880 "ECDSA signature verification failed.", error_cleanup);
881 }
882
883 error_cleanup:
884 OSSL_FREE(eccKey, EC_KEY);
885 return r;
886 }
887
888 /**
889 * Gets an object with the TPM-relevant public information of an OpenSSL
890 * RSA public key.
891 *
892 * @param[in,out] profile The crypto profile from which parameters are retrieved
893 * @param[in] publicKey The public key for which the public information is
894 * retrieved
895 * @param[out] tpmPublic The public information of publicKey
896 *
897 * @retval TSS2_RC_SUCCESS on success
898 * @retval TSS2_FAPI_RC_BAD_REFERENCE if profile, publicKey or tpmPublic is NULL
899 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
900 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
901 */
902 static TSS2_RC
903 get_rsa_tpm2b_public_from_evp(
904 EVP_PKEY *publicKey,
905 TPM2B_PUBLIC *tpmPublic)
906 {
907 /* Check for NULL parameters */
908 return_if_null(publicKey, "publicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
909 return_if_null(tpmPublic, "tpmPublic is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
910
911 /* Extract the public information */
912 TSS2_RC r = TSS2_RC_SUCCESS;
913 RSA *rsaKey = EVP_PKEY_get1_RSA(publicKey);
914 return_if_null(rsaKey, "Out of memory.", TSS2_FAPI_RC_MEMORY);
915 const BIGNUM *e = NULL, *n = NULL;
916 int rsaKeySize = RSA_size(rsaKey);
917
918 #if OPENSSL_VERSION_NUMBER < 0x10100000
919 e = rsaKey->e;
920 n = rsaKey->n;
921 #else /* OPENSSL_VERSION_NUMBER < 0x10100000 */
922 RSA_get0_key(rsaKey, &n, &e, NULL);
923 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
924 tpmPublic->publicArea.unique.rsa.size = rsaKeySize;
925 if (1 != ifapi_bn2binpad(n, &tpmPublic->publicArea.unique.rsa.buffer[0],
926 rsaKeySize)) {
927 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
928 "Write big num byte buffer", cleanup);
929 }
930 tpmPublic->publicArea.parameters.rsaDetail.keyBits = rsaKeySize * 8;
931 tpmPublic->publicArea.parameters.rsaDetail.exponent = BN_get_word(e);
932
933 cleanup:
934 OSSL_FREE(rsaKey, RSA);
935 return r;
936 }
937
938 /**
939 * Gets an object with the TPM-relevant public information of an OpenSSL
940 * ECC public key.
941 *
942 * @param[in,out] profile The crypto profile to retrieve parameters from.
943 * @param[in] publicKey The public key for which the public information is
944 * retrieved
945 * @param[out] tpmPublic The public information of publicKey
946 *
947 * @retval TSS2_RC_SUCCESS on success
948 * @retval TSS2_FAPI_RC_BAD_REFERENCE if profile, publicKey or tpmPublic is NULL
949 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
950 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
951 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
952 * the function.
953 */
954 static TSS2_RC
955 get_ecc_tpm2b_public_from_evp(
956 EVP_PKEY *publicKey,
957 TPM2B_PUBLIC *tpmPublic)
958 {
959 /* Check for NULL parameters */
960 return_if_null(publicKey, "publicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
961 return_if_null(tpmPublic, "tpmPublic is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
962
963 /* Initialize variables that will contain the relevant information */
964 TSS2_RC r = TSS2_RC_SUCCESS;
965 EC_KEY *ecKey = EVP_PKEY_get1_EC_KEY(publicKey);
966 return_if_null(ecKey, "Out of memory.", TSS2_FAPI_RC_MEMORY);
967 const EC_GROUP *ecGroup;
968 const EC_POINT *publicPoint;
969 int curveId;
970 size_t ecKeySize;
971 BIGNUM *bnX = NULL;
972 BIGNUM *bnY = NULL;
973 TPMI_ECC_CURVE tpmCurveId;
974
975 if (!ecKey) {
976 return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "No ECC key!");
977 }
978
979 /* Retrieve the relevant information and write it to tpmPublic */
980 ecGroup = EC_KEY_get0_group(ecKey);
981 publicPoint = EC_KEY_get0_public_key(ecKey);
982 curveId = EC_GROUP_get_curve_name(ecGroup);
983 ecKeySize = EC_GROUP_get_degree(ecGroup) / 8;
984 tpmPublic->publicArea.unique.ecc.x.size = ecKeySize;
985 tpmPublic->publicArea.unique.ecc.y.size = ecKeySize;
986
987 if (!(bnX = BN_new())) {
988 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Create bignum", cleanup);
989 }
990
991 if (!(bnY = BN_new())) {
992 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Create bignum", cleanup);
993 }
994
995 if (1 != EC_POINT_get_affine_coordinates_GFp(ecGroup, publicPoint,
996 bnX, bnY, NULL)) {
997 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
998 "Get affine coordinates", cleanup);
999 }
1000 if (1 != ifapi_bn2binpad(bnX, &tpmPublic->publicArea.unique.ecc.x.buffer[0],
1001 ecKeySize)) {
1002 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1003 "Write big num byte buffer", cleanup);
1004 }
1005 if (1 != ifapi_bn2binpad(bnY, &tpmPublic->publicArea.unique.ecc.y.buffer[0],
1006 ecKeySize)) {
1007 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1008 "Write big num byte buffer", cleanup);
1009 }
1010 switch (curveId) {
1011 case NID_X9_62_prime192v1:
1012 tpmCurveId = TPM2_ECC_NIST_P192;
1013 break;
1014 case NID_secp224r1:
1015 tpmCurveId = TPM2_ECC_NIST_P224;
1016 break;
1017 case NID_X9_62_prime256v1:
1018 tpmCurveId = TPM2_ECC_NIST_P256;
1019 break;
1020 case NID_secp384r1:
1021 tpmCurveId = TPM2_ECC_NIST_P384;
1022 break;
1023 case NID_secp521r1:
1024 tpmCurveId = TPM2_ECC_NIST_P521;
1025 break;
1026 default:
1027 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
1028 "Curve %x not implemented", cleanup, curveId);
1029 }
1030 tpmPublic->publicArea.parameters.eccDetail.curveID = tpmCurveId;
1031
1032 cleanup:
1033 OSSL_FREE(ecKey, EC_KEY);
1034 OSSL_FREE(bnX, BN);
1035 OSSL_FREE(bnY, BN);
1036 return r;
1037 }
1038
1039 /**
1040 * Converts a given PEM key into an EVP public key object.
1041 *
1042 * @param[in] pemKey A byte buffer holding the PEM key to convert
1043 * @param[out] publicKey An EVP public key
1044 *
1045 * @retval TSS2_FAPI_RC_BAD_REFERENCE if any of the parameters is NULL
1046 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
1047 * @retval TSS2_FAPI_RC_BAD_VALUE if the PEM key could not be decoded
1048 */
1049 static TSS2_RC
1050 ifapi_get_evp_from_pem(const char *pemKey, EVP_PKEY **publicKey) {
1051 /* Check for NULL parameters */
1052 return_if_null(pemKey, "pemKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1053 return_if_null(publicKey, "publicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1054
1055 TSS2_RC r = TSS2_RC_SUCCESS;
1056 BIO *bufio = NULL;
1057
1058 /* Use BIO for conversion */
1059 bufio = BIO_new_mem_buf((void *)pemKey, strlen(pemKey));
1060 goto_if_null(bufio, "BIO buffer could not be allocated.",
1061 TSS2_FAPI_RC_MEMORY, cleanup);
1062
1063 /* Convert the key */
1064 *publicKey = PEM_read_bio_PUBKEY(bufio, NULL, NULL, NULL);
1065 goto_if_null(*publicKey, "PEM format could not be decoded.",
1066 TSS2_FAPI_RC_BAD_VALUE, cleanup);
1067 cleanup:
1068 BIO_free(bufio);
1069 return r;
1070 }
1071
1072 /**
1073 * Returns the TPM algorithm identifier that matches to the signature algorithm
1074 * of a given PEM key.
1075 *
1076 * @param[in] pemKey The public key from which the signature algorithm is retrieved
1077 *
1078 * @retval TPM2_ALG_RSA if pemKey holds an RSA key
1079 * @retval TPM2_ALG_ECC if pemKey holds an ECC key
1080 * @retval TPM2_ALG_ERROR if the signature algorithm could not be determined
1081 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1082 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1083 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1084 * the function.
1085 */
1086 TPM2_ALG_ID
1087 ifapi_get_signature_algorithm_from_pem(const char *pemKey) {
1088 /* Check for NULL parameters */
1089 return_if_null(pemKey, "pemKey is NULL", TPM2_ALG_ERROR);
1090
1091 /* Get an EVP object for the key */
1092 EVP_PKEY * publicKey = NULL;
1093 TPM2_ALG_ID algorithmId = TPM2_ALG_ERROR;
1094 TSS2_RC r = ifapi_get_evp_from_pem(pemKey, &publicKey);
1095 if (r != TSS2_RC_SUCCESS || publicKey == NULL) {
1096 LOG_ERROR("Could not get an EVP key from the PEM key");
1097 algorithmId = TPM2_ALG_ERROR;
1098 goto cleanup;
1099 }
1100
1101 /* Determine the signature algorithm of the converted key */
1102 if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_RSA) {
1103 algorithmId = TPM2_ALG_RSA;
1104 } else if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_EC) {
1105 algorithmId = TPM2_ALG_ECC;
1106 } else {
1107 algorithmId = TPM2_ALG_ERROR;
1108 }
1109
1110 cleanup:
1111 OSSL_FREE(publicKey, EVP_PKEY);
1112 return algorithmId;
1113 }
1114
1115 /**
1116 * Gets an object with the TPM-relevant public information of a PEM encoded
1117 * public key. The information is gathered from the key itself and the currently
1118 * used FAPI profile.
1119 *
1120 * @param[in] pemKey A byte buffer holding the PEM encoded public key for
1121 * which the public information is retrieved
1122 * @param[out] tpmPublic The public information of pemKey
1123 *
1124 * @retval TSS2_RC_SUCCESS on success
1125 * @retval TSS2_FAPI_RC_BAD_REFERENCE if profile, pemKey or tpmPublic is NULL
1126 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
1127 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1128 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1129 * the function.
1130 */
1131 TSS2_RC
1132 ifapi_get_tpm2b_public_from_pem(
1133 const char *pemKey,
1134 TPM2B_PUBLIC *tpmPublic)
1135 {
1136 /* Check for NULL parameters */
1137 return_if_null(pemKey, "pemKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1138 return_if_null(tpmPublic, "public is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1139
1140 TSS2_RC r = TSS2_RC_SUCCESS;
1141 EVP_PKEY *publicKey = NULL;
1142 r = ifapi_get_evp_from_pem(pemKey, &publicKey);
1143 goto_if_error(r, "Get EVP key from PEM", cleanup);
1144
1145 if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_RSA) {
1146 tpmPublic->publicArea.type = TPM2_ALG_RSA;
1147 r = get_rsa_tpm2b_public_from_evp(publicKey, tpmPublic);
1148 goto_if_error(r, "Get public for RSA key.", cleanup);
1149
1150 } else if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_EC) {
1151 tpmPublic->publicArea.type = TPM2_ALG_ECC;
1152 r = get_ecc_tpm2b_public_from_evp(publicKey, tpmPublic);
1153 goto_if_error(r, "Get public for ECC key.", cleanup);
1154 } else {
1155 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong key_type", cleanup);
1156 }
1157 cleanup:
1158 OSSL_FREE(publicKey, EVP_PKEY);
1159 return r;
1160 }
1161
1162 /**
1163 * Verifies the signature created by a Quote command.
1164 *
1165 * @param[in] keyObject A FAPI key with which the signature is verified
1166 * @param[in] signature A byte buffer holding the signature
1167 * @param[in] signatureSize The size of signature in bytes
1168 * @param[in] digest The digest of the signature
1169 * @param[in] digestSize The size of digest in bytes
1170 * @param[in] signatureScheme The signature scheme
1171 *
1172 * @retval TSS2_RC_SUCCESS on success
1173 * @retval TSS2_FAPI_RC_BAD_REFERENCE if keyObject, signature, digest
1174 * or signatureScheme is NULL
1175 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
1176 * @retval TSS2_FAPI_RC_BAD_VALUE if the PEM encoded key could not be decoded
1177 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1178 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the verification of the
1179 * signature fails
1180 */
1181 TSS2_RC
1182 ifapi_verify_signature_quote(
1183 const IFAPI_OBJECT *keyObject,
1184 const uint8_t *signature,
1185 size_t signatureSize,
1186 const uint8_t *digest,
1187 size_t digestSize,
1188 const TPMT_SIG_SCHEME *signatureScheme)
1189 {
1190 /* Check for NULL parameters */
1191 return_if_null(keyObject, "keyObject is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1192 return_if_null(signature, "signature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1193 return_if_null(digest, "digest is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1194 return_if_null(signatureScheme, "signatureScheme is NULL",
1195 TSS2_FAPI_RC_BAD_REFERENCE);
1196
1197 TSS2_RC r = TSS2_RC_SUCCESS;
1198 char *public_pem_key = NULL;
1199 int pem_size;
1200 EVP_PKEY *publicKey = NULL;
1201 BIO *bufio = NULL;
1202 EVP_PKEY_CTX *pctx = NULL;
1203 EVP_MD_CTX *mdctx = NULL;
1204
1205 /* Check whether or not the key is valid */
1206 if (keyObject->objectType == IFAPI_KEY_OBJ) {
1207 /* Compute public key */
1208 r = ifapi_pub_pem_key_from_tpm(&keyObject->misc.key.public, &public_pem_key,
1209 &pem_size);
1210 goto_if_error(r, "Compute public PEM key.", error_cleanup);
1211 } else if (keyObject->objectType == IFAPI_EXT_PUB_KEY_OBJ) {
1212 public_pem_key = strdup(keyObject->misc.ext_pub_key.pem_ext_public);
1213 check_oom(public_pem_key);
1214 } else {
1215 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong object type",
1216 error_cleanup);
1217 }
1218
1219 /* Create an OpenSSL object for the key */
1220 bufio = BIO_new_mem_buf((void *)public_pem_key,
1221 strlen(public_pem_key));
1222 goto_if_null(bufio, "BIO buffer could not be allocated.",
1223 TSS2_FAPI_RC_MEMORY, error_cleanup);
1224
1225 publicKey = PEM_read_bio_PUBKEY(bufio, NULL, NULL, NULL);
1226 goto_if_null(publicKey, "PEM format could not be decoded.",
1227 TSS2_FAPI_RC_BAD_VALUE, error_cleanup);
1228
1229 /* Create the hash engine */
1230 if (!(mdctx = EVP_MD_CTX_create())) {
1231 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EVP_MD_CTX_create",
1232 error_cleanup);
1233 }
1234
1235 const EVP_MD *hashAlgorithm = get_hash_md(signatureScheme->details.any.hashAlg);
1236 if (!hashAlgorithm) {
1237 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid hash alg.",
1238 error_cleanup);
1239 }
1240
1241 /* Verify the digest of the signature */
1242 if (1 != EVP_DigestVerifyInit(mdctx, &pctx, hashAlgorithm, NULL, publicKey)) {
1243 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EVP_DigestVerifyInit",
1244 error_cleanup);
1245 }
1246 goto_if_null(pctx, "Out of memory", TSS2_FAPI_RC_MEMORY, error_cleanup);
1247 if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_RSA) {
1248 int padding = get_sig_scheme(signatureScheme->scheme);
1249 if (!padding) {
1250 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1251 "Invalid padding scheme.", error_cleanup);
1252 }
1253 if (1 != EVP_PKEY_CTX_set_rsa_padding(pctx, padding)) {
1254 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1255 "EVP_PKEY_CTX_set_rsa_padding", error_cleanup);
1256 }
1257 }
1258
1259 if (1 != EVP_DigestVerifyUpdate(mdctx, digest, digestSize)) {
1260 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1261 "EVP_DigestVerifyUpdate", error_cleanup);
1262 }
1263 if (1 != EVP_DigestVerifyFinal(mdctx, signature, signatureSize)) {
1264 goto_error(r, TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED,
1265 "EVP_DigestSignFinal", error_cleanup);
1266 }
1267
1268 error_cleanup:
1269 if (mdctx != NULL) {
1270 EVP_MD_CTX_destroy(mdctx);
1271 }
1272 SAFE_FREE(public_pem_key);
1273 EVP_PKEY_free(publicKey);
1274 BIO_free(bufio);
1275 return r;
1276 }
1277
1278 /**
1279 * Verifies a signature using a given FAPI public key.
1280 *
1281 * @param[in] keyObject The FAPI public key used for verification
1282 * @param[in] signature The signature to verify
1283 * @param[in] signatureSize The size of signature in bytes
1284 * @param[in] digest The digest of the signature
1285 * @param[in] digestSize The size of digest in bytes
1286 *
1287 * @retval TSS2_RC_SUCCESS In case of success
1288 * @retval TSS2_FAPI_RC_BAD_REFERENCE if keyObject, signature or digest is NULL
1289 * @retval TSS2_FAPI_RC_BAD_VALUE if the type of the key is wrong
1290 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
1291 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1292 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED if the verification of the
1293 * signature fails
1294 *
1295 */
1296 TSS2_RC
1297 ifapi_verify_signature(
1298 const IFAPI_OBJECT *keyObject,
1299 const uint8_t *signature,
1300 size_t signatureSize,
1301 const uint8_t *digest,
1302 size_t digestSize)
1303 {
1304 /* Check for NULL parameters */
1305 return_if_null(keyObject, "keyObject is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1306 return_if_null(signature, "signature is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1307 return_if_null(digest, "digest is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1308
1309 TSS2_RC r = TSS2_RC_SUCCESS;
1310 char *public_pem_key = NULL;
1311 int pem_size;
1312 EVP_PKEY *publicKey = NULL;
1313 BIO *bufio = NULL;
1314
1315 /* Check whether or not the key is valid */
1316 if (keyObject->objectType == IFAPI_KEY_OBJ) {
1317 /* Compute public key */
1318 r = ifapi_pub_pem_key_from_tpm(&keyObject->misc.key.public, &public_pem_key,
1319 &pem_size);
1320 goto_if_error(r, "Compute public PEM key.", error_cleanup);
1321 } else if (keyObject->objectType == IFAPI_EXT_PUB_KEY_OBJ) {
1322 public_pem_key = strdup(keyObject->misc.ext_pub_key.pem_ext_public);
1323 check_oom(public_pem_key);
1324 } else {
1325 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong object type",
1326 error_cleanup);
1327 }
1328
1329 /* Convert the key to an OpenSSL object */
1330 bufio = BIO_new_mem_buf((void *)public_pem_key,
1331 strlen(public_pem_key));
1332 goto_if_null(bufio, "Out of memory.", TSS2_FAPI_RC_MEMORY, error_cleanup);
1333 publicKey = PEM_read_bio_PUBKEY(bufio, NULL, NULL, NULL);
1334 goto_if_null(publicKey, "PEM format could not be decoded.",
1335 TSS2_FAPI_RC_MEMORY, error_cleanup);
1336
1337 /* Call a suitable local function for the verification */
1338 if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_RSA) {
1339 r = rsa_verify_signature(publicKey, signature, signatureSize, digest,
1340 digestSize);
1341 goto_if_error(r, "Verify RSA signature.", error_cleanup);
1342
1343 } else if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_EC) {
1344 r = ecdsa_verify_signature(publicKey, signature, signatureSize,
1345 digest, digestSize);
1346 goto_if_error(r, "Verify ECC signature", error_cleanup);
1347
1348 } else {
1349 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong key type",
1350 error_cleanup);
1351 }
1352
1353 error_cleanup:
1354 SAFE_FREE(public_pem_key);
1355 EVP_PKEY_free(publicKey);
1356 if (bufio)
1357 BIO_free(bufio);
1358 return r;
1359 }
1360
1361 /**
1362 * Returns the digest size of a given hash algorithm.
1363 *
1364 * @param[in] hashAlgorithm The TSS identifier of the hash algorithm
1365 *
1366 * @return The size of the digest produced by the hash algorithm if
1367 * hashAlgorithm is valid
1368 * @retval 0 if hashAlgorithm is invalid
1369 */
1370 size_t
1371 ifapi_hash_get_digest_size(TPM2_ALG_ID hashAlgorithm)
1372 {
1373 switch (hashAlgorithm) {
1374 case TPM2_ALG_SHA1:
1375 return TPM2_SHA1_DIGEST_SIZE;
1376 break;
1377 case TPM2_ALG_SHA256:
1378 return TPM2_SHA256_DIGEST_SIZE;
1379 break;
1380 case TPM2_ALG_SHA384:
1381 return TPM2_SHA384_DIGEST_SIZE;
1382 break;
1383 case TPM2_ALG_SHA512:
1384 return TPM2_SHA512_DIGEST_SIZE;
1385 break;
1386 case TPM2_ALG_SM3_256:
1387 return TPM2_SM3_256_DIGEST_SIZE;
1388 break;
1389 default:
1390 return 0;
1391 }
1392 }
1393
1394 /**
1395 * Converts a TSS hash algorithm identifier into an OpenSSL hash algorithm
1396 * identifier object.
1397 *
1398 * @param[in] hashAlgorithm The TSS hash algorithm identifier to convert
1399 *
1400 * @retval A suitable OpenSSL identifier object if one could be found
1401 * @retval NULL if no suitable identifier object could be found
1402 */
1403 static const EVP_MD *
1404 get_ossl_hash_md(TPM2_ALG_ID hashAlgorithm)
1405 {
1406 switch (hashAlgorithm) {
1407 case TPM2_ALG_SHA1:
1408 return EVP_sha1();
1409 break;
1410 case TPM2_ALG_SHA256:
1411 return EVP_sha256();
1412 break;
1413 case TPM2_ALG_SHA384:
1414 return EVP_sha384();
1415 break;
1416 case TPM2_ALG_SHA512:
1417 return EVP_sha512();
1418 break;
1419 default:
1420 return NULL;
1421 }
1422 }
1423
1424 /**
1425 * Starts the computation of a hash digest.
1426 *
1427 * @param[out] context The created hash context (callee-allocated).
1428 * @param[in] hashAlgorithm The TSS hash identifier for the hash algorithm to use.
1429 *
1430 * @retval TSS2_RC_SUCCESS on success.
1431 * @retval TSS2_FAPI_RC_BAD_VALUE if hashAlgorithm is invalid
1432 * @retval TSS2_FAPI_RC_BAD_REFERENCE if context is NULL
1433 * @retval TSS2_FAPI_RC_MEMORY if memory cannot be allocated
1434 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1435 */
1436 TSS2_RC
1437 ifapi_crypto_hash_start(IFAPI_CRYPTO_CONTEXT_BLOB **context,
1438 TPM2_ALG_ID hashAlgorithm)
1439 {
1440 /* Check for NULL parameters */
1441 return_if_null(context, "context is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1442
1443 /* Initialize the hash context */
1444 TSS2_RC r = TSS2_RC_SUCCESS;
1445 LOG_DEBUG("call: context=%p hashAlg=%" PRIu16, context, hashAlgorithm);
1446 IFAPI_CRYPTO_CONTEXT *mycontext = NULL;
1447 mycontext = calloc(1, sizeof(IFAPI_CRYPTO_CONTEXT));
1448 return_if_null(mycontext, "Out of memory", TSS2_FAPI_RC_MEMORY);
1449
1450 if (!(mycontext->osslHashAlgorithm = get_ossl_hash_md(hashAlgorithm))) {
1451 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
1452 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
1453 hashAlgorithm);
1454 }
1455
1456 if (!(mycontext->hashSize = ifapi_hash_get_digest_size(hashAlgorithm))) {
1457 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
1458 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
1459 hashAlgorithm);
1460 }
1461
1462 if (!(mycontext->osslContext = EVP_MD_CTX_create())) {
1463 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Error EVP_MD_CTX_create",
1464 cleanup);
1465 }
1466
1467 if (1 != EVP_DigestInit_ex(mycontext->osslContext,
1468 mycontext->osslHashAlgorithm, get_engine())) {
1469 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Error EVP_DigestInit_ex",
1470 cleanup);
1471 }
1472
1473 *context = (IFAPI_CRYPTO_CONTEXT_BLOB *) mycontext;
1474
1475 return TSS2_RC_SUCCESS;
1476
1477 cleanup:
1478 if (mycontext->osslContext)
1479 EVP_MD_CTX_destroy(mycontext->osslContext);
1480 SAFE_FREE(mycontext);
1481
1482 return r;
1483 }
1484
1485 /**
1486 * Updates the digest value of a hash object with data from a byte buffer.
1487 *
1488 * @param[in,out] context The hash context that will be updated
1489 * @param[in] buffer The data for the update
1490 * @param[in] size The size of data in bytes
1491 *
1492 * @retval TSS2_RC_SUCCESS on success.
1493 * @retval TSS2_FAPI_RC_BAD_REFERENCE for invalid parameters.
1494 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1495 */
1496 TSS2_RC
1497 ifapi_crypto_hash_update(IFAPI_CRYPTO_CONTEXT_BLOB *context,
1498 const uint8_t *buffer, size_t size)
1499 {
1500 /* Check for NULL parameters */
1501 return_if_null(context, "context is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1502 return_if_null(buffer, "buffer is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1503
1504 LOG_DEBUG("called for context %p, buffer %p and size %zd", context, buffer,
1505 size);
1506
1507 /* Update the digest */
1508 IFAPI_CRYPTO_CONTEXT *mycontext = (IFAPI_CRYPTO_CONTEXT *) context;
1509 LOGBLOB_DEBUG(buffer, size, "Updating hash with");
1510
1511 if (1 != EVP_DigestUpdate(mycontext->osslContext, buffer, size)) {
1512 return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL hash update");
1513 }
1514
1515 return TSS2_RC_SUCCESS;
1516 }
1517
1518 /**
1519 * Gets the digest value from a hash context and closes it.
1520 *
1521 * @param[in,out] context The hash context that is released
1522 * @param[out] digest The buffer for the digest value
1523 * @param[out] digestSize The size of digest in bytes. Can be NULL
1524 *
1525 * @retval TSS2_RC_SUCCESS on success
1526 * @retval TSS2_FAPI_RC_BAD_REFERENCE if context or digest is NULL
1527 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1528 */
1529 TSS2_RC
1530 ifapi_crypto_hash_finish(IFAPI_CRYPTO_CONTEXT_BLOB **context,
1531 uint8_t *digest, size_t *digestSize)
1532 {
1533 /* Check for NULL parameters */
1534 return_if_null(context, "context is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1535 return_if_null(digest, "digest is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1536
1537 unsigned int computedDigestSize = 0;
1538
1539 LOG_TRACE("called for context-pointer %p, digest %p and size-pointer %p",
1540 context, digest, digestSize);
1541 /* Compute the digest */
1542 IFAPI_CRYPTO_CONTEXT *mycontext = *context;
1543 if (1 != EVP_DigestFinal_ex(mycontext->osslContext, digest,
1544 &computedDigestSize)) {
1545 return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL error.");
1546 }
1547
1548 if (computedDigestSize != mycontext->hashSize) {
1549 return_error(TSS2_FAPI_RC_GENERAL_FAILURE,
1550 "Invalid size computed by EVP_DigestFinal_ex");
1551 }
1552
1553 LOGBLOB_DEBUG(digest, mycontext->hashSize, "finish hash");
1554
1555 if (digestSize != NULL) {
1556 *digestSize = mycontext->hashSize;
1557 }
1558
1559 /* Finalize the hash context */
1560 EVP_MD_CTX_destroy(mycontext->osslContext);
1561 free(mycontext);
1562 *context = NULL;
1563
1564 return TSS2_RC_SUCCESS;
1565 }
1566
1567 /**
1568 * Aborts a hash operation and finalizes the hash context. It will be set to
1569 * NULL.
1570 *
1571 * @param[in,out] context The context of the digest object.
1572 */
1573 void
1574 ifapi_crypto_hash_abort(IFAPI_CRYPTO_CONTEXT_BLOB **context)
1575 {
1576 LOG_TRACE("called for context-pointer %p", context);
1577 if (context == NULL || *context == NULL) {
1578 LOG_DEBUG("Null-Pointer passed");
1579 return;
1580 }
1581 IFAPI_CRYPTO_CONTEXT *mycontext = (IFAPI_CRYPTO_CONTEXT *) * context;
1582
1583 EVP_MD_CTX_destroy(mycontext->osslContext);
1584 free(mycontext);
1585 *context = NULL;
1586 }
1587
1588 /**
1589 * Get url to download crl from certificate.
1590 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1591 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1592 * the function.
1593 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1594 * @retval TSS2_FAPI_RC_NO_CERT if an error did occur during certificate downloading.
1595 */
1596 TSS2_RC
1597 get_crl_from_cert(X509 *cert, X509_CRL **crl)
1598 {
1599 TSS2_RC r = TSS2_RC_SUCCESS;
1600 unsigned char* url = NULL;
1601 unsigned char *crl_buffer = NULL;
1602 size_t crl_buffer_size;
1603 int nid = NID_crl_distribution_points;
1604 STACK_OF(DIST_POINT) * dist_points = (STACK_OF(DIST_POINT) *)X509_get_ext_d2i(cert, nid, NULL, NULL);
1605 int curl_rc;
1606
1607 *crl = NULL;
1608 for (int i = 0; i < sk_DIST_POINT_num(dist_points); i++)
1609 {
1610 DIST_POINT *dp = sk_DIST_POINT_value(dist_points, i);
1611 DIST_POINT_NAME *distpoint = dp->distpoint;
1612 if (distpoint->type==0)
1613 {
1614 for (int j = 0; j < sk_GENERAL_NAME_num(distpoint->name.fullname); j++)
1615 {
1616 GENERAL_NAME *gen_name = sk_GENERAL_NAME_value(distpoint->name.fullname, j);
1617 ASN1_IA5STRING *asn1_str = gen_name->d.uniformResourceIdentifier;
1618 SAFE_FREE(url);
1619 url = (unsigned char *)strdup((char *)asn1_str->data);
1620 goto_if_null2(url, "Out of memory", r, TSS2_FAPI_RC_MEMORY, cleanup);
1621 }
1622 }
1623 }
1624
1625 curl_rc = ifapi_get_curl_buffer(url, &crl_buffer, &crl_buffer_size);
1626 if (curl_rc != 0) {
1627 goto_error(r, TSS2_FAPI_RC_NO_CERT, "Get crl.", cleanup);
1628 }
1629
1630 OpenSSL_add_all_algorithms();
1631
1632 unsigned const char* tmp_ptr1 = crl_buffer;
1633 unsigned const char** tmp_ptr2 = &tmp_ptr1;
1634
1635 if (!d2i_X509_CRL(crl, tmp_ptr2, crl_buffer_size)) {
1636 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Can't convert crl.", cleanup);
1637 }
1638
1639 cleanup:
1640 SAFE_FREE(crl_buffer);
1641 CRL_DIST_POINTS_free(dist_points);
1642 SAFE_FREE(url);
1643 return r;
1644 }
1645
1646 /**
1647 * Converts a TPM certificate buffer to the PEM format.
1648 *
1649 * @param[in] certBuffer A byte buffer holding the certificate
1650 * @param[in] certBufferSize The size of certBuffer in bytes
1651 * @param[out] pemCert A byte buffer where the PEM-formatted certificate is
1652 * stored
1653 * @param[out] certAlgorithmId The key type of the certified key
1654 * @param[out] tpmPublic The public key of the certificate in TPM format.
1655 *
1656 * @retval TSS2_RC_SUCCESS on success
1657 * @retval TSS2_FAPI_RC_BAD_REFERENCE if certBuffer or pemCert is NULL
1658 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
1659 * @retval TSS2_FAPI_RC_BAD_VALUE, if the certificate is invalid
1660 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1661 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1662 * the function.
1663 */
1664 TSS2_RC
1665 ifapi_cert_to_pem(
1666 const uint8_t *certBuffer,
1667 size_t certBufferSize,
1668 char **pemCert,
1669 TPM2_ALG_ID *certAlgorithmId,
1670 TPM2B_PUBLIC *tpmPublic)
1671 {
1672 /* Check for NULL parameters */
1673 return_if_null(certBuffer, "certBuffer is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1674 return_if_null(pemCert, "pemCert is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1675
1676 TSS2_RC r = TSS2_RC_SUCCESS;
1677 X509 *cert = NULL;
1678 BIO *bio = NULL;
1679 EVP_PKEY *publicKey = NULL;
1680 int pemCertSize;
1681
1682 if (!d2i_X509(&cert, (const unsigned char **)&certBuffer, certBufferSize)) {
1683 LOGBLOB_ERROR(certBuffer, certBufferSize, "Bad certificate data");
1684 return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid certificate.");
1685 }
1686 *pemCert = NULL;
1687
1688 /* Memory IO will be used for OSSL key conversion */
1689 bio = BIO_new(BIO_s_mem());
1690 return_if_null(bio, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1691
1692 if (!PEM_write_bio_X509(bio, cert)) {
1693 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "PEM_write_bio_X509", cleanup);
1694 }
1695 /* Determine the size of the data written */
1696 pemCertSize = BIO_get_mem_data(bio, pemCert);
1697 *pemCert = malloc(pemCertSize + 1);
1698 goto_if_null(pemCert, "Out of memory.", TSS2_FAPI_RC_MEMORY, cleanup);
1699
1700 /* Get the byte buffer written to the BIO object */
1701 int readSize = BIO_read(bio, *pemCert, pemCertSize);
1702 if (readSize != pemCertSize) {
1703 SAFE_FREE(*pemCert);
1704 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid BIO_read",
1705 cleanup);
1706 }
1707 (*pemCert)[pemCertSize] = '\0';
1708
1709 publicKey = X509_get_pubkey(cert);
1710 goto_if_null(publicKey, "No public key in certificate.",
1711 TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
1712
1713 if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_RSA) {
1714 tpmPublic->publicArea.type = TPM2_ALG_RSA;
1715 r = get_rsa_tpm2b_public_from_evp(publicKey, tpmPublic);
1716 goto_if_error(r, "Get public for RSA key.", cleanup);
1717
1718 } else if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_EC) {
1719 tpmPublic->publicArea.type = TPM2_ALG_ECC;
1720 r = get_ecc_tpm2b_public_from_evp(publicKey, tpmPublic);
1721 goto_if_error(r, "Get public for ECC key.", cleanup);
1722 } else {
1723 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong key_type", cleanup);
1724 }
1725
1726 if (certAlgorithmId != NULL) {
1727 switch (EVP_PKEY_id(publicKey)) {
1728 case EVP_PKEY_RSA:
1729 *certAlgorithmId = TPM2_ALG_RSA;
1730 break;
1731 case EVP_PKEY_EC:
1732 *certAlgorithmId = TPM2_ALG_ECC;
1733 break;
1734 default:
1735 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong certificate (key type).",
1736 cleanup);
1737 }
1738 }
1739 cleanup:
1740 BIO_free(bio);
1741 OSSL_FREE(cert, X509);
1742 OSSL_FREE(publicKey, EVP_PKEY);
1743 return r;
1744 }
1745
1746 /**
1747 * Returns a suitable hash algorithm for a given digest size.
1748 *
1749 * @param[in] size The size of the digest
1750 * @param[out] hashAlgorithm A suitable hash algorithm for the digest size
1751 *
1752 * @retval TSS2_RC_SUCCESS on success
1753 * @retval TSS2_FAPI_RC_BAD_REFERENCE if hashAlgorithm is NULL
1754 * @retval TSS2_FAPI_RC_BAD_VALUE if the digest size is invalid
1755 */
1756 TSS2_RC
1757 ifapi_get_hash_alg_for_size(uint16_t size, TPMI_ALG_HASH *hashAlgorithm)
1758 {
1759 /* Check for NULL parameters */
1760 return_if_null(hashAlgorithm, "hashAlgorithm is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
1761
1762 /* Determine the hash algorithm */
1763 switch (size) {
1764 case TPM2_SHA1_DIGEST_SIZE:
1765 *hashAlgorithm = TPM2_ALG_SHA1;
1766 return TSS2_RC_SUCCESS;
1767 case TPM2_SHA256_DIGEST_SIZE:
1768 *hashAlgorithm = TPM2_ALG_SHA256;
1769 return TSS2_RC_SUCCESS;
1770 case TPM2_SHA384_DIGEST_SIZE:
1771 *hashAlgorithm = TPM2_ALG_SHA384;
1772 return TSS2_RC_SUCCESS;
1773 case TPM2_SHA512_DIGEST_SIZE:
1774 *hashAlgorithm = TPM2_ALG_SHA512;
1775 return TSS2_RC_SUCCESS;
1776 default:
1777 return TSS2_FAPI_RC_BAD_VALUE;
1778 }
1779 }
1780
1781 /** Convert PEM certificate to OSSL format.
1782 *
1783 * @param[in] pem_cert Certificate in PEM format.
1784 * @retval X509 OSSL certificate object.
1785 * @retval NULL If the conversion fails.
1786 */
1787 static X509
1788 *get_X509_from_pem(const char *pem_cert)
1789 {
1790 if (!pem_cert) {
1791 return NULL;
1792 }
1793 BIO *bufio = NULL;
1794 X509 *cert = NULL;
1795
1796 /* Use BIO for conversion */
1797 size_t pem_length = strlen(pem_cert);
1798 bufio = BIO_new_mem_buf((void *)pem_cert, pem_length);
1799 if (!bufio)
1800 return NULL;
1801 /* Convert the certificate */
1802 cert = PEM_read_bio_X509(bufio, NULL, NULL, NULL);
1803 BIO_free(bufio);
1804 return cert;
1805 }
1806
1807 /** Get public information for key of a pem certificate.
1808 *
1809 * @param[in] pem_cert The pem certificate.
1810 * @param[out] tpm_public The public information of the key in TPM format.
1811 *
1812 * @retval TSS2_RC_SUCCESS on success
1813 * @retval TSS2_FAPI_RC_BAD_VALUE if the conversion fails.
1814 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if openssl errors occur.
1815 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1816 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1817 */
1818 TSS2_RC
1819 ifapi_get_public_from_pem_cert(const char* pem_cert, TPM2B_PUBLIC *tpm_public)
1820 {
1821 TSS2_RC r = TSS2_RC_SUCCESS;
1822 X509 *cert = NULL;
1823 EVP_PKEY *public_key = NULL;
1824
1825 cert = get_X509_from_pem(pem_cert);
1826 return_if_null(cert, "Invalid certificate.", TSS2_FAPI_RC_BAD_VALUE);
1827
1828 public_key = X509_get_pubkey(cert);
1829 goto_if_null(public_key, "No public key in certificate.",
1830 TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
1831
1832 if (EVP_PKEY_type(EVP_PKEY_id(public_key)) == EVP_PKEY_RSA) {
1833 tpm_public->publicArea.type = TPM2_ALG_RSA;
1834 r = get_rsa_tpm2b_public_from_evp(public_key, tpm_public);
1835 goto_if_error(r, "Get public for RSA key.", cleanup);
1836
1837 } else if (EVP_PKEY_type(EVP_PKEY_id(public_key)) == EVP_PKEY_EC) {
1838 tpm_public->publicArea.type = TPM2_ALG_ECC;
1839 r = get_ecc_tpm2b_public_from_evp(public_key, tpm_public);
1840 goto_if_error(r, "Get public for ECC key.", cleanup);
1841 } else {
1842 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Wrong key_type", cleanup);
1843 }
1844 cleanup:
1845 OSSL_FREE(cert, X509);
1846 OSSL_FREE(public_key, EVP_PKEY);
1847 return r;
1848 }
1849
1850 /** Convert buffer from DER format to X509 certificate.
1851 *
1852 * @param[in] cert_buffer Certificate in DER format.
1853 * @aparm[in] cert_buffer_size Size of DER certificate.
1854 * @retval X509 OSSL certificate object.
1855 * @retval NULL If the conversion fails.
1856 */
1857 static X509
1858 *get_cert_from_buffer(unsigned char *cert_buffer, size_t cert_buffer_size)
1859 {
1860 unsigned char *buffer = cert_buffer;
1861 X509 *cert = NULL;
1862
1863 unsigned const char* tmp_ptr1 = buffer;
1864 unsigned const char** tmp_ptr2 = &tmp_ptr1;
1865
1866 if (!d2i_X509(&cert, tmp_ptr2, cert_buffer_size))
1867 return NULL;
1868 return cert;
1869 }
1870
1871 /**
1872 * Verify EK certificate read from TPM.
1873 *
1874 * @param[in] root_cert_pem The vendor root certificate.
1875 * @param[in] intermed_cert_pem The vendor intermediate certificate.
1876 * @param[in] ek_cert_pem The ek certificate from TPM.
1877 *
1878 * @retval TSS2_RC_SUCCESS on success
1879 * @retval TSS2_FAPI_RC_BAD_VALUE if the verification was no successful.
1880 * @retval TSS2_FAPI_RC_NO_CERT if an error did occur during certificate downloading.
1881 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1882 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1883 */
1884 TSS2_RC
1885 ifapi_verify_ek_cert(
1886 char* root_cert_pem,
1887 char* intermed_cert_pem,
1888 char* ek_cert_pem)
1889 {
1890 TSS2_RC r = TSS2_RC_SUCCESS;
1891 X509 *root_cert = NULL;
1892 X509 *intermed_cert = NULL;
1893 X509 *ek_cert = NULL;
1894 X509_STORE *store = NULL;
1895 X509_STORE_CTX *ctx = NULL;
1896 X509_CRL *crl_intermed = NULL;
1897 X509_CRL *crl_ek = NULL;
1898 int i;
1899 size_t ui;
1900 AUTHORITY_INFO_ACCESS *info = NULL;
1901 ASN1_IA5STRING *uri = NULL;
1902 unsigned char * url;
1903 unsigned char *cert_buffer = NULL;
1904 size_t cert_buffer_size;
1905 int curl_rc;
1906
1907 ek_cert = get_X509_from_pem(ek_cert_pem);
1908 goto_if_null2(ek_cert, "Failed to convert PEM certificate to DER.",
1909 r, TSS2_FAPI_RC_BAD_VALUE, cleanup);
1910
1911 if (intermed_cert_pem) {
1912 intermed_cert = get_X509_from_pem(intermed_cert_pem);
1913 goto_if_null2(intermed_cert, "Failed to convert PEM certificate to DER.",
1914 r, TSS2_FAPI_RC_BAD_VALUE, cleanup);
1915 } else {
1916 /* Get uri for ek intermediate certificate. */
1917 OpenSSL_add_all_algorithms();
1918 info = X509_get_ext_d2i(ek_cert, NID_info_access, NULL, NULL);
1919
1920 for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
1921 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
1922 if (ad->location->type != GEN_URI) {
1923 continue;
1924 }
1925 uri = ad->location->d.uniformResourceIdentifier;
1926 url = uri->data;
1927 curl_rc = ifapi_get_curl_buffer(url, &cert_buffer, &cert_buffer_size);
1928 if (curl_rc != 0) {
1929 goto_error(r, TSS2_FAPI_RC_NO_CERT, "Get certificate.", cleanup);
1930 }
1931 goto_if_null2(cert_buffer, "No certificate downloaded", r,
1932 TSS2_FAPI_RC_NO_CERT, cleanup);
1933 }
1934 goto_if_null2(cert_buffer, "No certificate downloaded", r,
1935 TSS2_FAPI_RC_NO_CERT, cleanup);
1936
1937 OpenSSL_add_all_algorithms();
1938 intermed_cert = get_cert_from_buffer(cert_buffer, cert_buffer_size);
1939
1940 SAFE_FREE(cert_buffer);
1941 goto_if_null2(intermed_cert, "Failed to create intermediate certificate.",
1942 r, TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
1943
1944 /* Get Certificate revocation list for Intermediate certificate */
1945 r = get_crl_from_cert(intermed_cert, &crl_intermed);
1946 goto_if_error(r, "Get crl for intermediate certificate.", cleanup);
1947
1948 /* Get Certificate revocation list for EK certificate */
1949 r = get_crl_from_cert(ek_cert, &crl_ek);
1950 goto_if_error(r, "Get crl for ek certificate.", cleanup);
1951 }
1952
1953 /* Prepare X509 certificate store */
1954
1955 store = X509_STORE_new();
1956
1957 goto_if_null2(store, "Failed to create X509 store.",
1958 r, TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
1959
1960 /* Add Certificate revocation list for EK certificate if one exists. */
1961 if (crl_ek) {
1962 /* Set the flags of the store to use CRLs. */
1963 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1964 if (1 != X509_STORE_add_crl(store, crl_ek)) {
1965 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1966 "Failed to add intermediate crl.", cleanup);
1967 }
1968 }
1969
1970 /* Add Certificate revocation list for intermediate certificate if one exists. */
1971 if (crl_intermed) {
1972 /* Set the flags of the store to use CRLs. */
1973 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1974 if (1 != X509_STORE_add_crl(store, crl_intermed)) {
1975 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1976 "Failed to add intermediate crl.", cleanup);
1977 }
1978 }
1979
1980 /* Add stored root certificates */
1981 for (ui = 0; ui < sizeof(root_cert_list) / sizeof(char *); ui++) {
1982 root_cert = get_X509_from_pem(root_cert_list[ui]);
1983 goto_if_null2(root_cert, "Failed to convert PEM certificate to DER.",
1984 r, TSS2_FAPI_RC_BAD_VALUE, cleanup);
1985 if (1 != X509_STORE_add_cert(store, root_cert)) {
1986 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
1987 "Failed to add root certificate", cleanup);
1988 }
1989 OSSL_FREE(root_cert, X509);
1990 }
1991
1992 /* Create root cert if passed as parameter */
1993 if (root_cert_pem) {
1994 root_cert = get_X509_from_pem(root_cert_pem);
1995 goto_if_null2(root_cert, "Failed to convert PEM certificate to DER.",
1996 r, TSS2_FAPI_RC_BAD_VALUE, cleanup);
1997
1998 if (1 != X509_STORE_add_cert(store, root_cert)) {
1999 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
2000 "Failed to add root certificate", cleanup);
2001 }
2002 OSSL_FREE(root_cert, X509);
2003 }
2004
2005 /* Verify intermediate certificate */
2006 ctx = X509_STORE_CTX_new();
2007 goto_if_null2(ctx, "Failed to create X509 store context.",
2008 r, TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
2009 if (1 != X509_STORE_CTX_init(ctx, store, intermed_cert, NULL)) {
2010 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
2011 "Failed to initialize X509 context.", cleanup);
2012 }
2013 if (1 != X509_verify_cert(ctx)) {
2014 int rc = X509_STORE_CTX_get_error(ctx);
2015 LOG_ERROR("%s", X509_verify_cert_error_string(rc));
2016 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
2017 "Failed to verify EK certificate", cleanup);
2018 }
2019 if (1 != X509_STORE_add_cert(store, intermed_cert)) {
2020 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
2021 "Failed to add intermediate certificate", cleanup);
2022 }
2023
2024 X509_STORE_CTX_cleanup(ctx);
2025 X509_STORE_CTX_free(ctx);
2026 ctx = NULL;
2027 ctx = X509_STORE_CTX_new();
2028 goto_if_null2(ctx, "Failed to create X509 store context.",
2029 r, TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
2030
2031 if (1 != X509_STORE_CTX_init(ctx, store, ek_cert, NULL)) {
2032 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
2033 "Failed to initialize X509 context.", cleanup);
2034 }
2035 /* Verify the EK certificate. */
2036 if (1 != X509_verify_cert(ctx)) {
2037 int rc = X509_STORE_CTX_get_error(ctx);
2038 LOG_ERROR("%s", X509_verify_cert_error_string(rc));
2039 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
2040 "Failed to verify EK certificate", cleanup);
2041 }
2042
2043 cleanup:
2044 if (ctx) {
2045 X509_STORE_CTX_cleanup(ctx);
2046 X509_STORE_CTX_free(ctx);
2047 }
2048 if (store)
2049 X509_STORE_free(store);
2050 OSSL_FREE(root_cert, X509);
2051 OSSL_FREE(intermed_cert, X509);
2052 OSSL_FREE(ek_cert, X509);
2053 OSSL_FREE(crl_intermed, X509_CRL);
2054 OSSL_FREE(crl_ek, X509_CRL);
2055 OSSL_FREE(info, AUTHORITY_INFO_ACCESS);
2056 return r;
2057 }
2058
2059 /** Compute the fingerprint of a TPM public key.
2060 *
2061 * @param[in] tpmPublicKey The public key created by the TPM
2062 * @param[in] hashAlg The hash algorithm used for fingerprint computation.
2063 * @param[out] fingerprint The fingerprint digest.
2064 *
2065 * @retval TSS2_RC_SUCCESS on success
2066 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
2067 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated
2068 * @retval TSS2_FAPI_BAD_REFERENCE if tpmPublicKey or pemKeySize are NULL
2069 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2070 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2071 * the function.
2072 */
2073 TSS2_RC
2074 ifapi_get_tpm_key_fingerprint(
2075 const TPM2B_PUBLIC *tpmPublicKey,
2076 TPMI_ALG_HASH hashAlg,
2077 TPM2B_DIGEST *fingerprint)
2078 {
2079 /* Check for NULL parameters */
2080 return_if_null(tpmPublicKey, "tpmPublicKey is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
2081
2082 EVP_PKEY *evpPublicKey = NULL;
2083 TSS2_RC r = TPM2_RC_SUCCESS;
2084 uint8_t *pubKeyDer = NULL;
2085 int pubKeyDerSize;
2086 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
2087 size_t hashSize;
2088 size_t fingerPrintSize;
2089
2090 if (!(hashSize = ifapi_hash_get_digest_size(hashAlg))) {
2091 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
2092 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
2093 hashAlg);
2094 }
2095
2096 evpPublicKey = EVP_PKEY_new();
2097 goto_if_null2(evpPublicKey, "Out of memory.", r, TSS2_FAPI_RC_MEMORY, cleanup);
2098
2099 if (tpmPublicKey->publicArea.type == TPM2_ALG_RSA) {
2100 r = ossl_rsa_pub_from_tpm(tpmPublicKey, evpPublicKey);
2101 } else if (tpmPublicKey->publicArea.type == TPM2_ALG_ECC)
2102 r = ossl_ecc_pub_from_tpm(tpmPublicKey, evpPublicKey);
2103 else {
2104 goto_error(r,TSS2_FAPI_RC_BAD_VALUE, "Invalid alg id.", cleanup);
2105 }
2106 goto_if_error(r, "Get ossl public key.", cleanup);
2107
2108 /* Convert the OpenSSL EVP pub key into DEF format */
2109 pubKeyDerSize = i2d_PUBKEY(evpPublicKey, &pubKeyDer);
2110 if (pubKeyDerSize == -1) {
2111 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL error", cleanup);
2112 }
2113
2114 /* Compute the digest of the DER public key */
2115 r = ifapi_crypto_hash_start(&cryptoContext, hashAlg);
2116 goto_if_error(r, "crypto hash start", cleanup);
2117
2118 HASH_UPDATE_BUFFER(cryptoContext,
2119 pubKeyDer, pubKeyDerSize, r, cleanup);
2120 r = ifapi_crypto_hash_finish(&cryptoContext,
2121 &fingerprint->buffer[0], &fingerPrintSize);
2122 goto_if_error(r, "crypto hash finish", cleanup);
2123
2124 fingerprint->size = fingerPrintSize;
2125
2126 cleanup:
2127 EVP_PKEY_free(evpPublicKey);
2128 SAFE_FREE(pubKeyDer);
2129 if (cryptoContext) {
2130 ifapi_crypto_hash_abort(&cryptoContext);
2131 }
2132 return r;
2133 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef FAPI_CRYPTO_H
6 #define FAPI_CRYPTO_H
7
8 #include "fapi_int.h"
9
10 TSS2_RC
11 ifapi_get_profile_sig_scheme(
12 const IFAPI_PROFILE *profile,
13 const TPMT_PUBLIC *tpmPublic,
14 TPMT_SIG_SCHEME *signatureScheme);
15
16 TSS2_RC
17 ifapi_der_sig_to_tpm(
18 const TPMT_PUBLIC *tpmPublic,
19 const unsigned char *signature,
20 size_t signatureSize,
21 TPMI_ALG_HASH hashAlgorithm,
22 TPMT_SIGNATURE *tpmSignature);
23
24 TSS2_RC
25 ifapi_tpm_ecc_sig_to_der(
26 const TPMT_SIGNATURE *tpmSignature,
27 uint8_t **signature,
28 size_t *signatureSize);
29
30 TSS2_RC
31 ifapi_pub_pem_key_from_tpm(
32 const TPM2B_PUBLIC *tpmPublicKey,
33 char **pemKey,
34 int *pemKeySize);
35
36 TSS2_RC
37 ifapi_verify_signature(
38 const IFAPI_OBJECT *keyObject,
39 const uint8_t *signature,
40 size_t signatureSize,
41 const uint8_t *digest,
42 size_t digestSize);
43
44 TSS2_RC
45 ifapi_verify_signature_quote(
46 const IFAPI_OBJECT *keyObject,
47 const uint8_t *signature,
48 size_t signatureSize,
49 const uint8_t *digest,
50 size_t digestSize,
51 const TPMT_SIG_SCHEME *signatureScheme);
52
53
54 typedef struct _IFAPI_CRYPTO_CONTEXT IFAPI_CRYPTO_CONTEXT_BLOB;
55
56 TSS2_RC
57 ifapi_crypto_hash_start(
58 IFAPI_CRYPTO_CONTEXT_BLOB **context,
59 TPM2_ALG_ID hashAlgorithm);
60
61 TSS2_RC
62 ifapi_crypto_hash_update(
63 IFAPI_CRYPTO_CONTEXT_BLOB *context,
64 const uint8_t *buffer,
65 size_t size);
66
67 TSS2_RC
68 ifapi_crypto_hash_finish(
69 IFAPI_CRYPTO_CONTEXT_BLOB **context,
70 uint8_t *digest,
71 size_t *digestSize);
72
73 void
74 ifapi_crypto_hash_abort(
75 IFAPI_CRYPTO_CONTEXT_BLOB **context);
76
77 TSS2_RC
78 ifapi_cert_to_pem(
79 const uint8_t *certBuffer,
80 size_t certBufferSize,
81 char **pemCert,
82 TPM2_ALG_ID *certAlgorithmId,
83 TPM2B_PUBLIC *tpmPublic);
84
85 size_t
86 ifapi_hash_get_digest_size(
87 TPM2_ALG_ID hashAlgorithm);
88
89 TSS2_RC
90 ifapi_get_tpm2b_public_from_pem(
91 const char *pemKey,
92 TPM2B_PUBLIC *tpmPublic);
93
94 TSS2_RC
95 ifapi_get_hash_alg_for_size(
96 uint16_t size,
97 TPMI_ALG_HASH *hashAlgorithm);
98
99 TSS2_RC
100 ifapi_get_public_from_pem_cert(
101 const char* pem_cert,
102 TPM2B_PUBLIC *tpm_public);
103
104 TSS2_RC
105 ifapi_initialize_sign_public(
106 TPM2_ALG_ID signatureAlgorithm,
107 TPM2B_PUBLIC *template);
108
109 TPM2_ALG_ID
110 ifapi_get_signature_algorithm_from_pem(
111 const char *pemKey);
112
113 TSS2_RC
114 ifapi_verify_ek_cert(
115 char* root_cert_pem,
116 char* intermed_cert_pem,
117 char* ek_cert_pem);
118
119 TSS2_RC
120 ifapi_get_tpm_key_fingerprint(
121 const TPM2B_PUBLIC *tpmPublicKey,
122 TPMI_ALG_HASH hashAlg,
123 TPM2B_DIGEST *fingerprint);
124
125 #endif /* FAPI_CRYPTO_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef FAPI_INT_H
6 #define FAPI_INT_H
7
8 #include "fapi_types.h"
9 #include "ifapi_policy_types.h"
10 #include "ifapi_policy_instantiate.h"
11 #include "ifapi_eventlog.h"
12 #include "ifapi_io.h"
13 #include "ifapi_profiles.h"
14 #include "ifapi_macros.h"
15 #include "ifapi_keystore.h"
16 #include "ifapi_policy_store.h"
17 #include "ifapi_config.h"
18
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <inttypes.h>
24 #include <stdarg.h>
25 #include <stdbool.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <json-c/json.h>
31 #include <poll.h>
32
33 #include "tss2_esys.h"
34 #include "tss2_fapi.h"
35
36 #define DEFAULT_LOG_DIR "/run/tpm2_tss"
37 #define IFAPI_PCR_LOG_FILE "pcr.log"
38 #define IFAPI_OBJECT_TYPE ".json"
39 #define IFAPI_OBJECT_FILE "object.json"
40 #define IFAPI_SRK_KEY_PATH "HS/SRK"
41
42 typedef UINT32 TSS2_KEY_TYPE;
43 #define TSS2_SRK 2
44 #define TSS2_EK 3
45 #define MIN_EK_CERT_HANDLE 0x1c00000
46 #define MIN_PLATFORM_CERT_HANDLE 0x01C08000
47 #define MAX_PLATFORM_CERT_HANDLE 0x01C0FFFF
48
49 typedef UINT8 IFAPI_SESSION_TYPE;
50 #define IFAPI_SESSION_GENEK 0x01
51 #define IFAPI_SESSION1 0x02
52 #define IFAPI_SESSION2 0x04
53
54 #define IFAPI_POLICY_PATH "policy"
55 #define IFAPI_NV_PATH "nv"
56 #define IFAPI_EXT_PATH "ext"
57 #define IFAPI_FILE_DELIM "/"
58 #define IFAPI_LIST_DELIM ":"
59 #define IFAPI_FILE_DELIM_CHAR '/'
60 #define IFAPI_PUB_KEY_DIR "ext"
61 #define IFAPI_POLICY_DIR "policy"
62 #define IFAPI_PEM_PUBLIC_STRING "-----BEGIN PUBLIC KEY-----"
63 #define IFAPI_PEM_PRIVATE_KEY "-----PRIVATE KEY-----"
64 #define IFAPI_JSON_TAG_POLICY "policy"
65 #define IFAPI_JSON_TAG_DUPLICATE "public_parent"
66
67
68 #if TPM2_MAX_NV_BUFFER_SIZE > TPM2_MAX_DIGEST_BUFFER
69 #define IFAPI_MAX_BUFFER_SIZE TPM2_MAX_NV_BUFFER_SIZE
70 #else
71 #define IFAPI_MAX_BUFFER_SIZE TPM2_MAX_DIGEST_BUFFER
72 #endif
73
74 #define IFAPI_FLUSH_PARENT true
75 #define IFAPI_NOT_FLUSH_PARENT false
76
77 /* Definition of FAPI buffer for TPM2B transmission */
78 typedef struct {
79 UINT16 size;
80 BYTE buffer[IFAPI_MAX_BUFFER_SIZE];
81 } IFAPI_MAX_BUFFER;
82
83 #define OSSL_FREE(S,TYPE) if((S) != NULL) {TYPE##_free((void*) (S)); (S)=NULL;}
84
85
86 #define FAPI_COPY_DIGEST(dest_buffer, dest_size, src, src_size) \
87 if (src_size > sizeof(TPMU_HA)) { \
88 return_error(TSS2_FAPI_RC_BAD_VALUE, "Digest size too large."); \
89 } \
90 memcpy(dest_buffer, (src), (src_size)); \
91 dest_size = src_size
92
93 #define HASH_UPDATE(CONTEXT, TYPE, OBJECT, R, LABEL) \
94 { \
95 uint8_t buffer[sizeof(TYPE)]; \
96 size_t offset = 0; \
97 R = Tss2_MU_ ## TYPE ## _Marshal(OBJECT, \
98 &buffer[0], sizeof(TYPE), &offset); \
99 goto_if_error(R, "Marshal for hash update", LABEL); \
100 R = ifapi_crypto_hash_update(CONTEXT, \
101 (const uint8_t *) &buffer[0], \
102 offset); \
103 goto_if_error(R, "crypto hash update", LABEL); }
104
105 #define HASH_UPDATE_BUFFER(CONTEXT, BUFFER, SIZE, R, LABEL) \
106 R = ifapi_crypto_hash_update(CONTEXT, \
107 (const uint8_t *) BUFFER, SIZE) ; \
108 goto_if_error(R, "crypto hash update", LABEL);
109
110 #define FAPI_SYNC(r,msg,label, ...) \
111 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) \
112 return TSS2_FAPI_RC_TRY_AGAIN; \
113 if (r != TSS2_RC_SUCCESS) { \
114 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
115 goto label; \
116 }
117
118 /** The states for the FAPI's object authorization state*/
119 enum IFAPI_GET_CERT_STATE {
120 GET_CERT_INIT = 0,
121 GET_CERT_WAIT_FOR_GET_CAP,
122 GET_CERT_GET_CERT_NV,
123 GET_CERT_GET_CERT_NV_FINISH,
124 GET_CERT_GET_CERT_READ_PUBLIC,
125 GET_CERT_READ_CERT
126 };
127
128 /** The states for the FAPI's cleanup after successful command execution*/
129 enum IFAPI_CLEANUP_STATE {
130 CLEANUP_INIT = 0,
131 CLEANUP_SESSION1,
132 CLEANUP_SESSION2,
133 CLEANUP_SRK
134 };
135
136 #define IFAPI_MAX_CAP_INFO 17
137
138 typedef struct {
139 char *description;
140 TPMS_CAPABILITY_DATA *capability;
141 } IFAPI_CAP_INFO;
142
143 typedef struct {
144 char *fapi_version; /**< The version string of FAPI */
145 char *fapi_config; /**< The configuration information */
146 IFAPI_CAP_INFO cap[IFAPI_MAX_CAP_INFO];
147 } IFAPI_INFO;
148
149 /** Type for representing FAPI template for keys
150 */
151 typedef struct {
152 TPMI_YES_NO system; /**< Store the object in the system wide
153 directory */
154 TPMI_YES_NO persistent; /**< Store key persistent in NV ram. */
155 UINT32 persistent_handle; /**< < Persistent handle which should be used */
156 TPM2B_PUBLIC public; /**< Template for public data */
157 } IFAPI_KEY_TEMPLATE;
158
159 /** Type for representing template for NV objects
160 */
161 typedef struct {
162 TPMI_YES_NO system; /**< Store the object in the system wide
163 directory */
164 TPMI_RH_HIERARCHY hierarchy; /**< Hierarchy for NV object. */
165 char *description; /**< Description of template. */
166 TPMS_NV_PUBLIC public; /**< Template for public data */
167 } IFAPI_NV_TEMPLATE;
168
169 /** Type for representing a external public key
170 */
171 typedef struct {
172 TPMT_SIG_SCHEME sig_scheme; /**< Signature scheme used for quote. */
173 TPMS_ATTEST attest; /**< Attestation data from Quote */
174 } FAPI_QUOTE_INFO;
175
176
177 /** The states for the FAPI's NV read state */
178 enum _FAPI_STATE_NV_READ {
179 NV_READ_INIT = 0,
180 NV_READ_AUTHORIZE,
181 NV_READ_AUTHORIZE2,
182 NV_READ_AUTH_SENT
183 };
184
185 /** The states for the FAPI's NV write state */
186 enum _FAPI_STATE_NV_WRITE {
187 NV2_WRITE_INIT = 0,
188 NV2_WRITE_READ,
189 NV2_WRITE_WAIT_FOR_SESSSION,
190 NV2_WRITE_NULL_AUTH_SENT,
191 NV2_WRITE_AUTH_SENT,
192 NV2_WRITE_WRITE_PREPARE,
193 NV2_WRITE_WRITE,
194 NV2_WRITE_AUTHORIZE,
195 NV2_WRITE_AUTHORIZE2
196 };
197
198 /** The data structure holding internal state of Fapi NV commands.
199 */
200 typedef struct {
201 char *nvPath ; /**< The name of the file for object serialization */
202 char *policyPath; /**< The name of the policy file */
203 TPM2B_NV_PUBLIC public; /**< The public info of the NV object. */
204 ESYS_TR esys_auth_handle; /**< The ESAPI handle for the NV auth object */
205 ESYS_TR esys_handle; /**< The ESAPI handle for the NV object */
206 size_t numBytes; /**< The number of bytes of a ESYS request */
207 UINT16 bytesRequested; /**< Bytes currently requested from TPM */
208 UINT16 offset; /**< Offset in TPM memory TPM */
209 size_t data_idx; /**< Offset in the read buffer */
210 const uint8_t *data; /**< Buffer for data to be written */
211 uint8_t *rdata; /**< Buffer for data to be read */
212 IFAPI_OBJECT auth_object; /**< Object used for authentication */
213 IFAPI_OBJECT nv_object; /**< Deserialized NV object */
214 TPM2B_AUTH auth; /**< The Password */
215 IFAPI_NV nv_obj; /**< The NV Object */
216 ESYS_TR auth_index; /**< The ESAPI handle of the authorization object */
217 uint64_t bitmap; /**< The bitmask for the SetBits command */
218 IFAPI_NV_TEMPLATE public_templ; /**< The template for nv creation, adjusted
219 appropriate by the passed flags */
220 enum _FAPI_STATE_NV_READ nv_read_state; /**< The current state of NV read */
221 enum _FAPI_STATE_NV_WRITE nv_write_state; /**< The current state of NV write*/
222 uint8_t *write_data;
223 char const *logData; /**< The event log for NV objects of type pcr */
224 json_object *jso_event_log; /**< logData in JSON format */
225 TPMI_RH_NV_INDEX maxNvIndex; /**< Max index for search for free index */
226 IFAPI_EVENT pcr_event; /**< Event to be added to log */
227 TPML_DIGEST_VALUES digests; /**< Digest for the event data of an extend */
228 bool skip_policy_computation; /**< switch whether policy needs to be computed */
229 } IFAPI_NV_Cmds;
230
231 /** The data structure holding internal state of Fapi_Initialize command.
232 */
233 typedef struct {
234 TPMS_CAPABILITY_DATA *capability; /* TPM capability data to check available algs */
235 } IFAPI_INITIALIZE;
236
237 /** The data structure holding internal state of Fapi_PCR commands.
238 */
239 typedef struct {
240 TPML_DIGEST_VALUES digest_list; /**< The digest list computed for the event */
241 TPML_DIGEST_VALUES *event_digests; /**< The digest list computed by TPM2_Event */
242 ESYS_TR PCR; /**< The handle of the PCR register to be extended */
243 TPML_PCR_SELECTION pcr_selection; /**< Selection used for Read and Quote */
244 TPML_PCR_SELECTION *pcr_selection_out; /**< Selection returned by PCR_Read */
245 UINT32 update_count;
246 TPML_DIGEST *pcrValues; /* The values returned by PCR_Read */
247 TPM2_HANDLE pcrIndex;
248 TPMI_ALG_HASH hashAlg;
249 const char *keyPath; /**< The implicit key path for PCR_Quote */
250 ESYS_TR handle; /**< The ESYS handle of the signing key */
251 IFAPI_OBJECT *key_object; /**< The IPAPI object of the signing key */
252 TPMS_CAPABILITY_DATA *capabilityData; /* TPM capability data to check available algs */
253 uint32_t *pcrList; /**< Array of PCR numbers */
254 size_t pcrListSize; /**< Size of PCR array */
255 TPM2B_DATA qualifyingData; /**< Nonce for quote command */
256 uint8_t const *eventData;
257 TPM2B_EVENT event;
258 size_t eventDataSize;
259 uint32_t const *hashAlgs;
260 uint32_t *hashAlgs2;
261 size_t numHashAlgs;
262 char const *quoteInfo;
263 TPM2B_ATTEST *tpm_quoted;
264 TPMT_SIGNATURE *tpm_signature;
265 uint8_t const *signature;
266 size_t signatureSize;
267 char const *logData;
268 char *pcrLog;
269 IFAPI_EVENT pcr_event;
270 json_object *event_list;
271 FAPI_QUOTE_INFO fapi_quote_info;
272 } IFAPI_PCR;
273
274 /** The data structure holding internal state of Fapi_SetDescription.
275 */
276 typedef struct {
277 char *description; /**< The description of the object */
278 UINT8_ARY appData; /**< Application data to be stored in object store. */
279 IFAPI_OBJECT object; /**< The IPAPI object to store the info*/
280 char *object_path; /**< The realative path to the object */
281 json_object *jso; /**< JSON object for storing the AppData */
282 char *jso_string; /**< JSON deserialized buffer */
283 } IFAPI_Path_SetDescription;
284
285 /** The data structure holding internal state of Fapi_GetRandom.
286 */
287 typedef struct {
288 size_t numBytes; /**< The number of random bytes to be generated */
289 size_t idx; /**< Current position in output buffer. */
290 UINT16 bytesRequested; /**< Byted currently requested from TPM */
291 uint8_t *data; /**< The buffer for the random data */
292 } IFAPI_GetRandom;
293
294 /** The data structure holding internal state of Fapi_Key_Setcertificate.
295 */
296 typedef struct {
297 const char *pem_cert; /**< The certifificate in pem or format */
298 char *pem_cert_dup; /**< The allocate certifificate */
299 const char *key_path; /**< The absolute key path */
300 NODE_STR_T *path_list; /**< The computed explicit path */
301 IFAPI_OBJECT key_object; /**< The IPAPI object for the certified key */
302 } IFAPI_Key_SetCertificate;
303
304 /** The states for the FAPI's key creation */
305 enum IFAPI_KEY_CREATE_STATE {
306 KEY_CREATE_INIT = 0,
307 KEY_CREATE_WAIT_FOR_SESSION,
308 KEY_CREATE_WAIT_FOR_PARENT,
309 KEY_CREATE_AUTH_SENT,
310 KEY_CREATE_WRITE_PREPARE,
311 KEY_CREATE_WRITE,
312 KEY_CREATE_FLUSH,
313 KEY_CREATE_CALCULATE_POLICY,
314 KEY_CREATE_WAIT_FOR_AUTHORIZATION,
315 KEY_CREATE_CLEANUP
316 };
317
318 /** The data structure holding internal state of Fapi_CreateKey.
319 */
320 typedef struct {
321 enum IFAPI_KEY_CREATE_STATE state;
322 const char *keyPath; /**< The pathname from the application */
323 NODE_STR_T *path_list; /**< The computed explicit path */
324 IFAPI_OBJECT parent; /**< The parent of the key for used for creation. */
325 IFAPI_OBJECT object; /**< The current object. */
326 IFAPI_KEY_TEMPLATE public_templ; /**< The template for the keys public data */
327 TPM2B_PUBLIC public; /**< The public data of the key */
328 TPM2B_SENSITIVE_CREATE inSensitive;
329 TPM2B_DATA outsideInfo;
330 TPML_PCR_SELECTION creationPCR;
331 ESYS_TR handle;
332 const char *authValue;
333 const char *policyPath;
334 const IFAPI_PROFILE *profile;
335 } IFAPI_Key_Create;
336
337 /** The data structure holding internal state of Fapi_EncryptDecrypt.
338 */
339 typedef struct {
340 char const *keyPath; /**< The implicit key path */
341 uint8_t const *in_data;
342 size_t in_dataSize;
343 IFAPI_OBJECT *key_object; /**< The IPAPI object for the encryption key */
344 uint8_t *out_data; /**< The output of symmetric encrypt/decryption */
345 ESYS_TR key_handle; /**< The ESYS handle of the encryption key */
346 size_t numBytes; /**< The number of bytes of a ESYS request */
347 size_t decrypt; /**< Switch whether to encrypt or decrypt */
348 UINT16 bytesRequested; /**< Bytes currently requested from TPM */
349 TPMT_RSA_DECRYPT rsa_scheme;
350 ESYS_TR object_handle;
351 char *policy_path;
352 ESYS_TR auth_session;
353 const IFAPI_PROFILE *profile;
354 } IFAPI_Data_EncryptDecrypt;
355
356 /** The states for signing */
357 enum FAPI_SIGN_STATE {
358 SIGN_INIT = 0,
359 SIGN_WAIT_FOR_SESSION,
360 SIGN_WAIT_FOR_KEY,
361 SIGN_AUTH_SENT,
362 SIGN_WAIT_FOR_FLUSH
363 };
364
365 /** The data structure holding internal state of Fapi_Sign.
366 */
367 typedef struct {
368 enum FAPI_SIGN_STATE state; /**< The state of the signing operation */
369 const char *keyPath; /**< The implicit key path */
370 ESYS_TR handle; /**< The ESYS handle of the signing key */
371 TPM2B_DIGEST digest; /**< The digest to be signed */
372 TPMT_SIG_SCHEME scheme; /**< The signature scheme from profile */
373 IFAPI_OBJECT *key_object; /**< The IPAPI object of the signing key */
374 TPMT_SIGNATURE *tpm_signature; /**< The signature in TPM format */
375 TPMI_YES_NO decrypt; /**< Switch for symmetric algs */
376 TPMT_SIGNATURE *signature; /**< Produced TPM singature */
377 char const *padding; /**< Optional padding parameter for key sign. */
378 } IFAPI_Key_Sign;
379
380 /** The data structure holding internal state of Fapi_Unseal.
381 */
382 typedef struct {
383 const char *keyPath; /**< The implicit key path */
384 IFAPI_OBJECT *object; /**< The IPAPI object storing the data to be unsealed */
385 TPM2B_SENSITIVE_DATA *unseal_data; /** The result of the esys unseal operation */
386 } IFAPI_Unseal;
387
388
389 /** The data structure holding internal state of Fapi_GetInfo.
390 */
391 typedef struct {
392 TPMS_CAPABILITY_DATA *capability_data; /**< The TPM capability for one property */
393 TPMS_CAPABILITY_DATA *fetched_data; /**< The data fetched in one TPM command */
394 size_t idx_info_cap;
395 IFAPI_INFO info_obj;
396 UINT32 property_count;
397 UINT32 property;
398 } IFAPI_GetInfo;
399
400 /** The states for the FAPI's hierarchy authorization state*/
401 enum IFAPI_HIERACHY_AUTHORIZATION_STATE {
402 HIERARCHY_CHANGE_AUTH_INIT = 0,
403 HIERARCHY_CHANGE_AUTH_NULL_AUTH_SENT,
404 HIERARCHY_CHANGE_AUTH_AUTH_SENT
405 };
406
407 /** The states for the FAPI's change policy authorization state*/
408 enum IFAPI_HIERACHY_POLICY_AUTHORIZATION_STATE {
409 HIERARCHY_CHANGE_POLICY_INIT = 0,
410 HIERARCHY_CHANGE_POLICY_NULL_AUTH_SENT,
411 HIERARCHY_CHANGE_POLICY_AUTH_SENT
412 };
413
414 /** The data structure holding internal state of Fapi_ChangeAuth.
415 */
416 typedef struct {
417 const char *entityPath; /**< The implicit key path */
418 ESYS_TR handle; /**< The ESYS handle of the key */
419 IFAPI_OBJECT *key_object; /**< The IPAPI object of the key */
420 const char *authValue; /**< The new auth value */
421 TPM2B_AUTH newAuthValue; /**< The new auth value */
422 TPM2B_PRIVATE *newPrivate; /**< New private data created by parend */
423 IFAPI_OBJECT object; /**< Deserialized NV object or hierarchy */
424 ESYS_TR nv_index; /**< NV handle of the object to be changed */
425 ESYS_TR hierarchy_handle; /**< NV handle of the hierarchy to be changed */
426 } IFAPI_Entity_ChangeAuth;
427
428 /** The data structure holding internal state of Fapi_AuthorizePolicy.
429 */
430 typedef struct {
431 const char *policyPath; /**< Policy with Policy to be authorized */
432 const char *signingKeyPath; /**< Key for policy signing */
433 TPM2B_DIGEST policyRef;
434 TPMS_POLICYAUTHORIZATION authorization;
435 } IFAPI_Fapi_AuthorizePolicy;
436
437 /** The data structure holding internal state of Fapi_WriteAuthorizeNv.
438 */
439 typedef struct {
440 const char *policyPath; /**< Policy with Policy to be authorized */
441 TPMI_ALG_HASH *hash_alg; /**< The hash alg used for digest computation */
442 size_t hash_size; /**< The digest size */
443 size_t digest_idx; /**< The index of the digest in the policy */
444 } IFAPI_api_WriteAuthorizeNv;
445
446 /** The data structure holding internal state of Provisioning.
447 */
448 typedef struct {
449 IFAPI_OBJECT hierarchy; /**< The current used hierarchy for CreatePrimary */
450 IFAPI_KEY_TEMPLATE public_templ; /**< The basic template for the keys public data */
451 TPM2B_PUBLIC public; /**< The public info of the created primary */
452 TPM2B_SENSITIVE_CREATE inSensitive;
453 TPM2B_DATA outsideInfo;
454 TPML_PCR_SELECTION creationPCR;
455 ESYS_TR handle;
456 const char *authValueLockout;
457 const char *authValueEh;
458 const char *policyPathEh;
459 const char *authValueSh;
460 const char *policyPathSh;
461 size_t digest_idx;
462 size_t hash_size;
463 TPM2_HANDLE cert_nv_idx;
464 ESYS_TR esys_nv_cert_handle;
465 char *pem_cert;
466 TPM2_ALG_ID cert_key_type;
467 size_t cert_count;
468 size_t cert_idx;
469 TPMS_CAPABILITY_DATA *capabilityData;
470 IFAPI_OBJECT hierarchy_object;
471 TPM2B_AUTH hierarchy_auth;
472 TPM2B_DIGEST policy_digest;
473 char *intermed_crt;
474 char *root_crt;
475 } IFAPI_Provision;
476
477 /** The data structure holding internal state of regenerate primary key.
478 */
479 typedef struct {
480 char *path; /**< Path of the primary (starting with hierarchy) */
481 IFAPI_OBJECT hierarchy; /**< The current used hierarchy for CreatePrimary */
482 IFAPI_OBJECT pkey_object;
483 TPM2B_SENSITIVE_CREATE inSensitive;
484 TPM2B_DATA outsideInfo;
485 TPML_PCR_SELECTION creationPCR;
486 ESYS_TR handle;
487 TPMI_DH_PERSISTENT persistent_handle;
488 } IFAPI_CreatePrimary;
489
490 /** The data structure holding internal state of key verify signature.
491 */
492 typedef struct {
493 const char *keyPath;
494 uint8_t const *signature;
495 size_t signatureSize;
496 uint8_t const *digest;
497 size_t digestSize;
498 IFAPI_OBJECT key_object;
499 } IFAPI_Key_VerifySignature;
500
501 /** The states for the FAPI's policy loading */
502 enum IFAPI_STATE_POLICY {
503 POLICY_INIT = 0,
504 POLICY_READ,
505 POLICY_READ_FINISH,
506 POLICY_INSTANTIATE_PREPARE,
507 POLICY_INSTANTIATE,
508 POLICY_EXECUTE,
509 POLICY_FLUSH
510 };
511
512 typedef struct IFAPI_POLICY_EXEC_CTX IFAPI_POLICY_EXEC_CTX;
513 typedef struct IFAPI_POLICYUTIL_STACK IFAPI_POLICYUTIL_STACK;
514
515 /** The states for session creation */
516 enum FAPI_CREATE_SESSION_STATE {
517 CREATE_SESSION_INIT = 0,
518 CREATE_SESSION,
519 WAIT_FOR_CREATE_SESSION
520 };
521
522 /** The data structure holding internal policy state.
523 */
524 typedef struct {
525 enum IFAPI_STATE_POLICY state;
526 struct TPMS_POLICY policy;
527 size_t digest_idx;
528 size_t hash_size;
529 char **pathlist; /**< The array of all objects in the search path */
530 TPMI_ALG_HASH hash_alg;
531 IFAPI_POLICY_EXEC_CTX *policy_stack; /**< The stack used for storing current policy information.
532 e.g. for retry the current index of policy elements hash
533 to be stored. */
534 IFAPI_POLICYUTIL_STACK *util_current_policy;
535 IFAPI_POLICYUTIL_STACK *policyutil_stack;
536 /**< The stack used for storing current policy information.
537 e.g. for retry the current index of policy elements hash
538 to be stored. */
539 ESYS_TR session; /**< Auxiliary variable to store created policy session.
540 The value will also be stored in the policy stack */
541 enum FAPI_CREATE_SESSION_STATE create_session_state;
542 char *path;
543 IFAPI_POLICY_EVAL_INST_CTX eval_ctx;
544 } IFAPI_POLICY_CTX;
545
546 /** The states for the IFAPI's policy loading */
547 enum IFAPI_STATE_FILE_SEARCH {
548 FSEARCH_INIT = 0,
549 FSEARCH_READ,
550 FSEARCH_OBJECT
551 };
552
553 /** The data structure holding internal policy state.
554 */
555 typedef struct {
556 enum IFAPI_STATE_FILE_SEARCH state;
557 char **pathlist; /**< The array of all objects in the search path */
558 size_t path_idx; /**< Index of array of objects to be searched */
559 size_t numPaths; /**< Number of all objects in data store */
560 char *current_path;
561 } IFAPI_FILE_SEARCH_CTX;
562
563 /** The states for the FAPI's key loading */
564 enum _FAPI_STATE_LOAD_KEY {
565 LOAD_KEY_GET_PATH = 0,
566 LOAD_KEY_READ_KEY,
567 LOAD_KEY_WAIT_FOR_PRIMARY,
568 LOAD_KEY_LOAD_KEY,
569 LOAD_KEY_AUTH,
570 LOAD_KEY_AUTHORIZE
571 };
572
573 /** The data structure holding internal state of export key.
574 */
575 typedef struct {
576 char const *pathOfKeyToDuplicate; /**< The relative path of the key to be exported */
577 char const *pathToPublicKeyOfNewParent; /**< The relative path of the new parent */
578 TPM2B_PUBLIC public_parent; /**< The public key of the new parent */
579 IFAPI_OBJECT *key_object; /**< The IPAPI object of the key to be duplicated */
580 IFAPI_OBJECT export_tree; /**< The complete tree to be exported */
581 IFAPI_OBJECT pub_key; /**< The public part of the new parent */
582 IFAPI_OBJECT dup_key; /**< The key to be duplicated or exported */
583 struct TPMS_POLICY policy;
584 ESYS_TR handle_ext_key;
585 } IFAPI_ExportKey;
586
587 /** The data structure holding internal state of export policy.
588 */
589 typedef struct {
590 char const *path; /**< Path of the object with the policy to be
591 exported */
592 IFAPI_OBJECT object; /**< Object corresponding to path */
593 } IFAPI_ExportPolicy;
594
595 /** The data structure holding internal state of import key.
596 */
597 typedef struct {
598 IFAPI_OBJECT object;
599 TPM2B_NAME parent_name;
600 IFAPI_OBJECT *parent_object;
601 IFAPI_OBJECT new_object;
602 char *parent_path;
603 char *out_path;
604 TPM2B_PRIVATE *private;
605 char *jso_string;
606 } IFAPI_ImportKey;
607
608
609 /** The data structure holding internal state of loading keys.
610 */
611 typedef struct {
612 enum _FAPI_STATE_LOAD_KEY state; /**< The current state of key loading */
613 NODE_STR_T *path_list; /**< The current used hierarchy for CreatePrimary */
614 NODE_OBJECT_T *key_list;
615 IFAPI_OBJECT auth_object;
616 size_t position;
617 ESYS_TR handle;
618 ESYS_TR parent_handle;
619 bool parent_handle_persistent;
620 IFAPI_OBJECT *key_object;
621 char *key_path;
622 } IFAPI_LoadKey;
623
624 /** The data structure holding internal state of entity delete.
625 */
626 typedef struct {
627 bool is_key; /**< Entity to be deleted is a key */
628 bool is_persistent_key; /**< Entity to be deleted is a key */
629 ESYS_TR new_object_handle;
630 TPM2_HANDLE permanentHandle; /**< The TPM permanent handle */
631 IFAPI_OBJECT auth_object; /**< Object used for authentication */
632 ESYS_TR auth_index; /**< The ESAPI handle of the nv authorization object */
633 char *path; /**< The name of the file to be deleted */
634 IFAPI_OBJECT object; /**< Deserialized object */
635 char **pathlist; /**< The array with the object files to be deleted */
636 size_t numPaths; /**< Size of array with the object files to be deleted */
637 size_t path_idx; /**< Index of array with the object files to be deleted */
638 } IFAPI_Entity_Delete;
639
640 /** The data structure holding internal state of list entities.
641 */
642 typedef struct {
643 const char *searchPath; /**< The path to searched for objectws */
644 } IFAPI_Entities_List;
645
646 /** Union for all input parameters.
647 *
648 * The input parameters of a command need to be stored in order to enable
649 * resubmission. This type provides the corresponding facilities.
650 */
651 typedef union {
652 IFAPI_Provision Provision;
653 IFAPI_Key_Create Key_Create;
654 IFAPI_Key_SetCertificate Key_SetCertificate;
655 IFAPI_Entity_ChangeAuth Entity_ChangeAuth;
656 IFAPI_Entity_Delete Entity_Delete;
657 IFAPI_Entities_List Entities_List;
658 IFAPI_Key_VerifySignature Key_VerifySignature;
659 IFAPI_Data_EncryptDecrypt Data_EncryptDecrypt;
660 IFAPI_PCR pcr;
661 IFAPI_INITIALIZE Initialize;
662 IFAPI_Path_SetDescription path_set_info;
663 IFAPI_Fapi_AuthorizePolicy Policy_AuthorizeNewPolicy;
664 IFAPI_api_WriteAuthorizeNv WriteAuthorizeNV;
665 IFAPI_ExportKey ExportKey;
666 IFAPI_ImportKey ImportKey;
667 IFAPI_Unseal Unseal;
668 IFAPI_GetInfo GetInfo;
669 IFAPI_ExportPolicy ExportPolicy;
670 } IFAPI_CMD_STATE;
671
672 /** The states for the FAPI's primary key regeneration */
673 enum _FAPI_STATE_PRIMARY {
674 PRIMARY_INIT = 0,
675 PRIMARY_READ_KEY,
676 PRIMARY_READ_HIERARCHY,
677 PRIMARY_READ_HIERARCHY_FINISH,
678 PRIMARY_AUTHORIZE_HIERARCHY,
679 PRIMARY_HAUTH_SENT,
680 PRIMARY_CREATED
681 };
682
683 /** The states for the FAPI's primary key regeneration */
684 enum _FAPI_STATE_SESSION {
685 SESSION_INIT = 0,
686 SESSION_WAIT_FOR_PRIMARY,
687 SESSION_CREATE_SESSION,
688 SESSION_WAIT_FOR_SESSION1,
689 SESSION_WAIT_FOR_SESSION2
690 };
691
692 /** The states for the FAPI's get random state */
693 enum _FAPI_STATE_GET_RANDOM {
694 GET_RANDOM_INIT = 0,
695 GET_RANDOM_SENT
696 };
697
698 /** The states for flushing objects */
699 enum _FAPI_FLUSH_STATE {
700 FLUSH_INIT = 0,
701 WAIT_FOR_FLUSH
702 };
703
704 /** The states for the FAPI's internal state machine */
705 enum _FAPI_STATE {
706 _FAPI_STATE_INIT = 0, /**< The initial state after creation or after
707 finishing a command. A new command can only
708 be issued in this state. */
709 _FAPI_STATE_INTERNALERROR, /**< A non-recoverable error occurred within the
710 ESAPI code. */
711 INITIALIZE_READ,
712 INITIALIZE_INIT_TCTI,
713 INITIALIZE_GET_CAP,
714 INITIALIZE_WAIT_FOR_CAP,
715 INITIALIZE_READ_PROFILE,
716 INITIALIZE_READ_PROFILE_INIT,
717
718 PROVISION_WAIT_FOR_GET_CAP1,
719 PROVISION_INIT_GET_CAP2,
720 PROVISION_WAIT_FOR_GET_CAP2,
721 PROVISION_GET_CERT_NV,
722 PROVISION_GET_CERT_NV_FINISH,
723 PROVISION_GET_CERT_READ_PUBLIC,
724 PROVISION_READ_CERT,
725 PROVISION_PREPARE_READ_ROOT_CERT,
726 PROVISION_READ_ROOT_CERT,
727 PROVISION_READ_PROFILE,
728 PROVISION_INIT_SRK,
729 PROVISION_AUTH_EK_NO_AUTH_SENT,
730 PROVISION_AUTH_EK_AUTH_SENT,
731 PROVISION_AUTH_SRK_NO_AUTH_SENT,
732 PROVISION_AUTH_SRK_AUTH_SENT,
733 PROVISION_EK_WRITE_PREPARE,
734 PROVISION_EK_WRITE,
735 PROVISION_EK_CHECK_CERT,
736 PROVISION_SRK_WRITE_PREPARE,
737 PROVISION_SRK_WRITE,
738 PROVISION_WAIT_FOR_EK_PERSISTENT,
739 PROVISION_WAIT_FOR_SRK_PERSISTENT,
740 PROVISION_CHANGE_LOCKOUT_AUTH,
741 PROVISION_CHANGE_EH_CHECK,
742 PROVISION_CHANGE_EH_AUTH,
743 PROVISION_CHANGE_SH_CHECK,
744 PROVISION_CHANGE_SH_AUTH,
745 PROVISION_EH_CHANGE_POLICY,
746 PROVISION_SH_CHANGE_POLICY,
747 PROVISION_LOCKOUT_CHANGE_POLICY,
748 PROVISION_FINISHED,
749 PROVISION_WRITE_SH,
750 PROVISION_WRITE_EH,
751 PROVISION_WRITE_LOCKOUT,
752 PROVISION_WRITE_LOCKOUT_PARAM,
753 PROVISION_FLUSH_SRK,
754 PROVISION_FLUSH_EK,
755 PROVISION_CHECK_FOR_VENDOR_CERT,
756 PROVISION_GET_VENDOR,
757
758 KEY_CREATE,
759
760 CREATE_SEAL,
761
762 KEY_SET_CERTIFICATE_READ,
763 KEY_SET_CERTIFICATE_WRITE,
764
765 KEY_GET_CERTIFICATE_READ,
766
767 GET_RANDOM_WAIT_FOR_SESSION,
768 GET_RANDOM_WAIT_FOR_RANDOM,
769 GET_RANDOM_CLEANUP,
770
771 NV_CREATE_READ_PROFILE,
772 NV_CREATE_READ_HIERARCHY,
773 NV_CREATE_AUTHORIZE_HIERARCHY,
774 NV_CREATE_GET_INDEX,
775 NV_CREATE_FIND_INDEX,
776 NV_CREATE_WAIT_FOR_SESSION,
777
778 NV_CREATE_AUTH_SENT,
779 NV_CREATE_WRITE,
780 NV_CREATE_CALCULATE_POLICY,
781
782 NV_WRITE_READ,
783 NV_WRITE_WRITE,
784 NV_WRITE_CLEANUP,
785
786 NV_EXTEND_READ,
787 NV_EXTEND_WAIT_FOR_SESSION,
788 NV_EXTEND_AUTHORIZE,
789 NV_EXTEND_AUTH_SENT,
790 NV_EXTEND_WRITE,
791 NV_EXTEND_CLEANUP,
792
793 NV_INCREMENT_READ,
794 NV_INCREMENT_WAIT_FOR_SESSION,
795 NV_INCREMENT_AUTHORIZE,
796 NV_INCREMENT_AUTH_SENT,
797 NV_INCREMENT_WRITE,
798 NV_INCREMENT_CLEANUP,
799
800 NV_SET_BITS_READ,
801 NV_SET_BITS_WAIT_FOR_SESSION,
802 NV_SET_BITS_AUTHORIZE,
803 NV_SET_BITS_AUTH_SENT,
804 NV_SET_BITS_WRITE,
805 NV_SET_BITS_CLEANUP,
806
807 NV_READ_READ,
808 NV_READ_WAIT,
809 NV_READ_WAIT_FOR_SESSION,
810 NV_READ_CLEANUP,
811
812 ENTITY_DELETE_GET_FILE,
813 ENTITY_DELETE_READ,
814 ENTITY_DELETE_WAIT_FOR_SESSION,
815 ENTITY_DELETE_NULL_AUTH_SENT_FOR_KEY,
816 ENTITY_DELETE_AUTH_SENT_FOR_KEY,
817 ENTITY_DELETE_NULL_AUTH_SENT_FOR_NV,
818 ENTITY_DELETE_AUTH_SENT_FOR_NV,
819 ENTITY_DELETE_KEY,
820 ENTITY_DELETE_AUTHORIZE_NV,
821 ENTITY_DELETE_FILE,
822 ENTITY_DELETE_POLICY,
823 ENTITY_DELETE_REMOVE_DIRS,
824
825 ENTITY_GET_TPM_BLOBS_READ,
826
827 KEY_SIGN_WAIT_FOR_KEY,
828 KEY_SIGN_WAIT_FOR_SIGN,
829 KEY_SIGN_CLEANUP,
830
831 ENTITY_CHANGE_AUTH_WAIT_FOR_SESSION,
832 ENTITY_CHANGE_AUTH_WAIT_FOR_KEY,
833 ENTITY_CHANGE_AUTH_AUTH_SENT,
834 ENTITY_CHANGE_AUTH_WAIT_FOR_FLUSH,
835 ENTITY_CHANGE_AUTH_WRITE_PREPARE,
836 ENTITY_CHANGE_AUTH_WRITE,
837 ENTITY_CHANGE_AUTH_WAIT_FOR_KEY_AUTH,
838 ENTITY_CHANGE_AUTH_WAIT_FOR_NV_READ,
839 ENTITY_CHANGE_AUTH_WAIT_FOR_NV_AUTH,
840 ENTITY_CHANGE_AUTH_WAIT_FOR_NV_CHANGE_AUTH,
841 ENTITY_CHANGE_AUTH_HIERARCHY_CHANGE_AUTH,
842 ENTITY_CHANGE_AUTH_HIERARCHY_READ,
843 ENTITY_CHANGE_AUTH_HIERARCHY_AUTHORIZE,
844 ENTITY_CHANGE_AUTH_CLEANUP,
845
846 DATA_ENCRYPT_WAIT_FOR_PROFILE,
847 DATA_ENCRYPT_WAIT_FOR_SESSION,
848 DATA_ENCRYPT_WAIT_FOR_KEY,
849 DATA_ENCRYPT_WAIT_FOR_FLUSH,
850 DATA_ENCRYPT_WAIT_FOR_RSA_ENCRYPTION,
851 DATA_ENCRYPT_CLEAN,
852
853 DATA_DECRYPT_WAIT_FOR_PROFILE,
854 DATA_DECRYPT_WAIT_FOR_SESSION,
855 DATA_DECRYPT_WAIT_FOR_KEY,
856 DATA_DECRYPT_WAIT_FOR_FLUSH,
857 DATA_DECRYPT_WAIT_FOR_RSA_DECRYPTION,
858 DATA_DECRYPT_AUTHORIZE_KEY,
859 DATA_DECRYPT_CLEANUP,
860
861 PCR_EXTEND_WAIT_FOR_SESSION,
862 PCR_EXTEND_WAIT_FOR_GET_CAP,
863 PCR_EXTEND_APPEND_EVENT_LOG,
864 PCR_EXTEND_FINISH,
865 PCR_EXTEND_CLEANUP,
866
867 PCR_READ_READ_PCR,
868 PCR_READ_READ_EVENT_LIST,
869
870 PCR_QUOTE_WAIT_FOR_GET_CAP,
871 PCR_QUOTE_WAIT_FOR_SESSION,
872 PCR_QUOTE_WAIT_FOR_KEY,
873 PCR_QUOTE_AUTH_SENT,
874 PCR_QUOTE_AUTHORIZE,
875 PCR_QUOTE_WAIT_FOR_FLUSH,
876 PCR_QUOTE_READ_EVENT_LIST,
877 PCR_QUOTE_CLEANUP,
878
879 PATH_SET_DESCRIPTION_READ,
880 PATH_SET_DESCRIPTION_WRITE,
881
882 PATH_GET_DESCRIPTION_READ,
883
884 APP_DATA_SET_READ,
885 APP_DATA_SET_WRITE,
886
887 AUTHORIZE_NEW_CALCULATE_POLICY,
888 AUTHORIZE_NEW_LOAD_KEY,
889 AUTHORIZE_NEW_KEY_SIGN_POLICY,
890 AUTHORIZE_NEW_WRITE_POLICY_PREPARE,
891 AUTHORIZE_NEW_WRITE_POLICY,
892 AUTHORIZE_NEW_CLEANUP,
893
894 WRITE_AUTHORIZE_NV_READ_NV,
895 WRITE_AUTHORIZE_NV_CALCULATE_POLICY,
896 WRITE_AUTHORIZE_NV_WRITE_NV_RAM_PREPARE,
897 WRITE_AUTHORIZE_NV_WRITE_NV_RAM,
898 WRITE_AUTHORIZE_NV_WRITE_OBJCECT,
899 WRITE_AUTHORIZE_NV_WRITE_POLICY_PREPARE,
900 WRITE_AUTHORIZE_NV_WRITE_POLICY,
901 WRITE_AUTHORIZE_NV_CLEANUP,
902
903 EXPORT_KEY_READ_PUB_KEY,
904 EXPORT_KEY_READ_PUB_KEY_PARENT,
905 EXPORT_KEY_WAIT_FOR_KEY,
906 EXPORT_KEY_WAIT_FOR_DUPLICATE,
907 EXPORT_KEY_WAIT_FOR_EXT_KEY,
908 EXPORT_KEY_WAIT_FOR_AUTHORIZATON,
909 EXPORT_KEY_WAIT_FOR_FLUSH1,
910 EXPORT_KEY_WAIT_FOR_FLUSH2,
911 EXPORT_KEY_CLEANUP,
912
913 IMPORT_KEY_WRITE_POLICY,
914 IMPORT_KEY_WRITE,
915 IMPORT_KEY_SEARCH,
916 IMPORT_KEY_LOAD_PARENT,
917 IMPORT_KEY_AUTHORIZE_PARENT,
918 IMPORT_KEY_IMPORT,
919 IMPORT_KEY_WAIT_FOR_FLUSH,
920 IMPORT_KEY_WRITE_OBJECT_PREPARE,
921 IMPORT_KEY_WRITE_OBJECT,
922 IMPORT_KEY_CLEANUP,
923
924 UNSEAL_WAIT_FOR_KEY,
925 UNSEAL_AUTHORIZE_OBJECT,
926 UNSEAL_WAIT_FOR_UNSEAL,
927 UNSEAL_WAIT_FOR_FLUSH,
928 UNSEAL_CLEANUP,
929
930 GET_PLATFORM_CERTIFICATE,
931
932 POLICY_EXPORT_READ_OBJECT,
933 POLICY_EXPORT_READ_OBJECT_FINISH,
934 POLICY_EXPORT_READ_POLICY,
935 POLICY_EXPORT_READ_POLICY_FINISH,
936
937 VERIFY_QUOTE_READ,
938
939 GET_INFO_GET_CAP,
940 GET_INFO_GET_CAP_MORE,
941 GET_INFO_WAIT_FOR_CAP
942 };
943
944 /** Structure holding FAPI callbacks and userData
945 *
946 * This structure holds the callback pointers and corresponding userData pointers for each of the
947 * three callback types of FAPI. They are set using Fapi_SetAuthCB, Fapi_SetBranchCB and
948 * Fapi_SetSignCB.
949 */
950 struct IFAPI_CALLBACKS {
951 Fapi_CB_Auth auth;
952 void *authData;
953 Fapi_CB_Branch branch;
954 void *branchData;
955 Fapi_CB_Sign sign;
956 void *signData;
957 Fapi_CB_PolicyAction action;
958 void *actionData;
959 };
960
961 /** The data structure holding internal state information.
962 *
963 * Each FAPI_CONTEXT respresents a logically independent connection to the TPM.
964 * It stores meta data information about object in order to calculate session
965 * auths and similar things.
966 */
967 struct FAPI_CONTEXT {
968 ESYS_CONTEXT *esys; /**< The ESYS context used internally to talk to
969 the TPM. */
970 struct IFAPI_CALLBACKS callbacks; /**< Callbacks for user interaction from FAPI */
971 struct IFAPI_IO io;
972 struct IFAPI_EVENTLOG eventlog;
973 struct IFAPI_KEYSTORE keystore;
974 struct IFAPI_POLICY_STORE pstore;
975 struct IFAPI_PROFILES profiles;
976
977 enum _FAPI_STATE state; /**< The current state of the command execution */
978 enum _FAPI_STATE_PRIMARY primary_state; /**< The current state of the primary regeneration */
979 enum _FAPI_STATE_SESSION session_state; /**< The current state of the session creation */
980 enum _FAPI_STATE_GET_RANDOM get_random_state; /**< The current state of get random */
981 enum IFAPI_HIERACHY_AUTHORIZATION_STATE hierarchy_state;
982 enum IFAPI_HIERACHY_POLICY_AUTHORIZATION_STATE hierarchy_policy_state;
983 enum IFAPI_GET_CERT_STATE get_cert_state;
984 enum _FAPI_FLUSH_STATE flush_object_state; /**< The current state of a flush operation */
985 enum IFAPI_CLEANUP_STATE cleanup_state; /**< The state of cleanup after command execution */
986 IFAPI_CONFIG config; /**< The profile independet configuration data */
987 UINT32 nv_buffer_max; /**< The maximal size for transfer of nv buffer content */
988 IFAPI_CMD_STATE cmd; /**< The state information of the currently executed
989 command */
990 IFAPI_NV_Cmds nv_cmd;
991 IFAPI_GetRandom get_random;
992 IFAPI_CreatePrimary createPrimary;
993 IFAPI_LoadKey loadKey;
994 ESYS_TR session1; /**< The first session used by FAPI */
995 ESYS_TR session2; /**< The second session used by FAPI */
996 ESYS_TR policy_session; /**< The policy session used by FAPI */
997 ESYS_TR ek_handle;
998 ESYS_TR srk_handle;
999 bool ek_persistent;
1000 bool srk_persistent;
1001 IFAPI_SESSION_TYPE session_flags;
1002 TPMA_SESSION session1_attribute_flags;
1003 TPMA_SESSION session2_attribute_flags;
1004 IFAPI_MAX_BUFFER aux_data; /**< tpm2b data to be transferred */
1005 IFAPI_POLICY_CTX policy; /**< The context of current policy. */
1006 IFAPI_FILE_SEARCH_CTX fsearch; /**< The context for object search in key/policy store */
1007 IFAPI_Key_Sign Key_Sign; /**< State information for key signing */
1008 enum IFAPI_IO_STATE io_state;
1009 NODE_OBJECT_T *object_list;
1010 IFAPI_OBJECT *duplicate_key; /**< Will be needed for policy execution */
1011 };
1012
1013 #define VENDOR_IFX 0x49465800
1014 #define VENDOR_INTC 0x494E5443
1015 #define VEDNOR_IBM 0x49424D20
1016
1017 #endif /* FAPI_INT_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef FAPI_POLICY_H
6 #define FAPI_POLICY_H
7
8 #include <stdint.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <json-c/json.h>
13 #include <json-c/json_util.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18
19 #include "ifapi_policy_types.h"
20 #include "ifapi_policy_json_serialize.h"
21 #include "ifapi_policy_json_deserialize.h"
22 #include "ifapi_policy.h"
23 #include "ifapi_policy_calculate.h"
24 #include "ifapi_policy_execute.h"
25 #include "ifapi_json_serialize.h"
26 #include "ifapi_json_deserialize.h"
27
28
29 #endif /* FAPI_POLICY_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef FAPI_TYPES_H
6 #define FAPI_TYPES_H
7
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <stdbool.h>
11
12 /** The data structure representing an unit8_t array.
13 */
14 typedef struct {
15 size_t size;
16 uint8_t *buffer;
17 } UINT8_ARY;
18
19 /** The data structure storing a linked list of strings.
20 *
21 * The structure is used for the processing of file paths
22 */
23 typedef struct str_node {
24 char *str; /**< A string of the string list */
25 bool free_string; /**< Indicates whether a free has to called on cleanup */
26 struct str_node *next; /**< Pointer to next element */
27 } NODE_STR_T;
28
29 /** The data structure storing a linked list of objects.
30 *
31 * The structure is used for the processing of file paths
32 */
33 typedef struct object_node {
34 void *object; /**< The pointer to the object */
35 size_t size; /**< Will be used only for BYTE arrays */
36 struct object_node *next; /**< Pointer to next element */
37 } NODE_OBJECT_T;
38
39 #endif /* FAPI_TYPES_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdarg.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <ctype.h>
19 #include <dirent.h>
20
21 #include "tss2_mu.h"
22 #include "fapi_util.h"
23 #include "fapi_crypto.h"
24 #include "ifapi_helpers.h"
25 #include "ifapi_json_serialize.h"
26 #include "ifapi_json_deserialize.h"
27 #include "tpm_json_deserialize.h"
28 #include "fapi_policy.h"
29 #include "ifapi_policyutil_execute.h"
30 #define LOGMODULE fapi
31 #include "util/log.h"
32 #include "util/aux_util.h"
33
34 /** State machine for flushing objects.
35 *
36 * @param[in] context The FAPI_CONTEXT.
37 * @param[in] handle of the object to be flushed.
38 *
39 * @retval TSS2_RC_SUCCESS on success.
40 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
41 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
42 * this function needs to be called again.
43 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
44 * operation already pending.
45 */
46 TSS2_RC
47 ifapi_flush_object(FAPI_CONTEXT *context, ESYS_TR handle)
48 {
49 TSS2_RC r = TSS2_RC_SUCCESS;
50
51 if (handle == ESYS_TR_NONE)
52 return r;
53
54 switch (context->flush_object_state) {
55 statecase(context->flush_object_state, FLUSH_INIT);
56 r = Esys_FlushContext_Async(context->esys, handle);
57 return_if_error(r, "Flush Object");
58 fallthrough;
59
60 statecase(context->flush_object_state, WAIT_FOR_FLUSH);
61 r = Esys_FlushContext_Finish(context->esys);
62 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
63 return TSS2_FAPI_RC_TRY_AGAIN;
64
65 return_if_error(r, "FlushContext");
66
67 context->flush_object_state = FLUSH_INIT;
68 return TSS2_RC_SUCCESS;
69
70 statecasedefault(context->flush_object_state);
71 }
72 }
73
74 /** Preparation for getting a session handle.
75 *
76 * The corresponding async call be executed and a session secret for encryption
77 * TPM2B parameters will be created.
78 *
79 * @param[in] esys The ESYS_CONTEXT.
80 * @param[in] saltkey The key which will be used for the encryption of the session
81 * secret.
82 * @param[in] profile The FAPI profile will be used to adjust the sessions symmetric
83 * parameters.
84 * @param[in] hashAlg The hash algorithm used for the session.
85 *
86 * @retval TSS2_RC_SUCCESS on success.
87 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
88 */
89 TSS2_RC
90 ifapi_get_session_async(ESYS_CONTEXT *esys, ESYS_TR saltkey, const IFAPI_PROFILE *profile,
91 TPMI_ALG_HASH hashAlg)
92 {
93 TSS2_RC r;
94
95 r = Esys_StartAuthSession_Async(esys, saltkey,
96 ESYS_TR_NONE,
97 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
98 NULL,
99 TPM2_SE_HMAC, &profile->session_symmetric,
100 hashAlg);
101 return_if_error(r, "Creating session.");
102
103 return TSS2_RC_SUCCESS;
104 }
105
106 /** Call for getting a session handle and adjust session parameters.
107 *
108 * @param[in] esys The ESYS_CONTEXT.
109 * @param[out] session The session handle.
110 * @param[in] flags The flags to adjust the session attributes.
111 *
112 * @retval TSS2_RC_SUCCESS on success.
113 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
114 */
115 TSS2_RC
116 ifapi_get_session_finish(ESYS_CONTEXT *esys, ESYS_TR *session,
117 TPMA_SESSION flags)
118 {
119 TSS2_RC r;
120 TPMA_SESSION sessionAttributes = 0;
121
122 /* Check whether authorization callback is defined */
123
124 r = Esys_StartAuthSession_Finish(esys, session);
125 if (r != TSS2_RC_SUCCESS)
126 return r;
127
128 sessionAttributes |= flags;
129 sessionAttributes |= TPMA_SESSION_CONTINUESESSION;
130
131 r = Esys_TRSess_SetAttributes(esys, *session, sessionAttributes,
132 0xff);
133 return_if_error(r, "Set session attributes.");
134
135 return TSS2_RC_SUCCESS;
136 }
137
138 /** Get the digest size of the policy of a FAPI object.
139 *
140 * @param[in] object The object with the correspodning policy.
141 *
142 * @retval The size of policy digest.
143 * @retval 0 if The object does not have a policy.
144 */
145 static size_t
146 policy_digest_size(IFAPI_OBJECT *object)
147 {
148 switch (object->objectType) {
149 case IFAPI_KEY_OBJ:
150 return object->misc.key.public.publicArea.authPolicy.size;
151 case IFAPI_NV_OBJ:
152 return object->misc.nv.public.nvPublic.authPolicy.size;
153 case IFAPI_HIERARCHY_OBJ:
154 return object->misc.hierarchy.authPolicy.size;
155 default:
156 return 0;
157 }
158 }
159
160 /** Add a object together with size as first element to a linked list.
161 *
162 * This function can e.g. used to add byte arrays together with their size
163 * to a linked list.
164 *
165 * @param[in] object The object to be added.
166 * @param[in] size The size of the object to be added.
167 * @param[in,out] object_list The linked list to be extended.
168 *
169 * @retval TSS2_RC_SUCCESS if the object was added.
170 * @retval TSS2_FAPI_RC_MEMORY If memory for the list extension cannot
171 * be allocated.
172 */
173 static TSS2_RC
174 push_object_with_size_to_list(void *object, size_t size, NODE_OBJECT_T **object_list)
175 {
176 TSS2_RC r;
177 r = push_object_to_list(object, object_list);
178 return_if_error(r, "Push object with size.");
179
180 (*object_list)->size = size;
181 return TSS2_RC_SUCCESS;
182 }
183
184 /** Initialize and expand the linked list representing a FAPI key path.
185 *
186 * From a passed key path the explicit key path will be determined. The
187 * profile and the hierarchy will be added if necessary and the extension
188 * is possible.
189 *
190 * @param[in] context_profile The profile used for extension of no profile is
191 * part of the path.
192 * @param[in] ipath The implicit pathname which has to be extended.
193 * @param[out] list_node1 The linked list for the passed key path without
194 * extensions.
195 * @param[out] current_list_node The current node in the list list_node1,
196 * which represent the tail not processed.
197 * @param[out] result The part of the new list which had been extended
198 * without the tail not processed.
199 *
200 * @retval TSS2_RC_SUCCESS: If the initialization was successful.
201 * @retval TSS2_FAPI_RC_BAD_VALUE If an invalid path was passed.
202 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
203 */
204 static TSS2_RC
205 init_explicit_key_path(
206 const char *context_profile,
207 const char *ipath,
208 NODE_STR_T **list_node1,
209 NODE_STR_T **current_list_node,
210 NODE_STR_T **result)
211 {
212 *list_node1 = split_string(ipath, IFAPI_FILE_DELIM);
213 NODE_STR_T *list_node = *list_node1;
214 char const *profile;
215 char *hierarchy;
216 TSS2_RC r = TSS2_RC_SUCCESS;
217
218 *result = NULL;
219 if (list_node == NULL) {
220 LOG_ERROR("Invalid path");
221 free_string_list(*list_node1);
222 return TSS2_FAPI_RC_BAD_VALUE;
223 }
224
225 /* Processing of the profile. */
226 if (strncmp("P_", list_node->str, 2) == 0) {
227 profile = list_node->str;
228 list_node = list_node->next;
229 } else {
230 profile = context_profile;
231 }
232 *result = init_string_list(profile);
233 if (*result == NULL) {
234 free_string_list(*list_node1);
235 LOG_ERROR("Out of memory");
236 return TSS2_FAPI_RC_MEMORY;
237 }
238 if (list_node == NULL) {
239 /* extend default hierarchy. */
240 hierarchy = "HS";
241 } else {
242 if (strcmp(list_node->str, "HS") == 0 ||
243 strcmp(list_node->str, "HE") == 0 ||
244 strcmp(list_node->str, "HP") == 0 ||
245 strcmp(list_node->str, "HN") == 0 ||
246 strcmp(list_node->str, "HP") == 0) {
247 hierarchy = list_node->str;
248 list_node = list_node->next;
249 }
250 /* Extend hierarchy. */
251 else if (strcmp(list_node->str, "EK") == 0) {
252 hierarchy = "HE";
253 } else if (list_node->next != NULL &&
254 (strcmp(list_node->str, "SRK") == 0 ||
255 strcmp(list_node->str, "SDK") == 0 ||
256 strcmp(list_node->str, "UNK") == 0 ||
257 strcmp(list_node->str, "UDK") == 0)) {
258 hierarchy = "HS";
259 } else {
260 hierarchy = "HS";
261 }
262 }
263
264 /* Extend the current result. */
265 if (!add_string_to_list(*result, hierarchy)) {
266 LOG_ERROR("Out of memory");
267 r = TSS2_FAPI_RC_MEMORY;
268 goto error;
269 }
270 if (list_node == NULL) {
271 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Explicit path can't be determined.",
272 error);
273 }
274 if (!add_string_to_list(*result, list_node->str)) {
275 LOG_ERROR("Out of memory");
276 r = TSS2_FAPI_RC_MEMORY;
277 goto error;
278 }
279 *current_list_node = list_node->next;
280 return TSS2_RC_SUCCESS;
281
282 error:
283 free_string_list(*result);
284 *result = NULL;
285 free_string_list(*list_node1);
286 *list_node1 = NULL;
287 return r;
288 }
289
290 /** Free first object of a linked list.
291 *
292 * Note: Referenced objects of the list have to be freed before.
293 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
294 */
295 static TSS2_RC
296 pop_object_from_list(FAPI_CONTEXT *context, NODE_OBJECT_T **object_list)
297 {
298 return_if_null(*object_list, "Pop from list.", TSS2_FAPI_RC_BAD_REFERENCE);
299
300 NODE_OBJECT_T *head = *object_list;
301 NODE_OBJECT_T *next = head->next;
302 *object_list = next;
303 ifapi_free_object(context, (void *)&head->object);
304 free(head);
305 return TSS2_RC_SUCCESS;
306 }
307
308 /** Set authorization value for a FAPI object.
309 *
310 * The callback which provides the auth value must be defined.
311 *
312 * @param[in,out] context The FAPI_CONTEXT.
313 * @param[in] auth_object The auth value will be assigned to this object.
314 * @param[in] description The description will be passed to the callback
315 * which delivers the auth value.
316 *
317 * @retval TSS2_RC_SUCCESS on success.
318 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for getting
319 * the auth value is not defined.
320 */
321 TSS2_RC
322 ifapi_set_auth(
323 FAPI_CONTEXT *context,
324 IFAPI_OBJECT *auth_object,
325 const char *description)
326 {
327 TSS2_RC r;
328 char *auth = NULL;
329 TPM2B_AUTH authValue = {.size = 0,.buffer = {0} };
330 char *obj_description;
331
332 obj_description = get_description(auth_object);
333
334 if (obj_description)
335 description = obj_description;
336
337 /* Check whether callback is defined. */
338 if (context->callbacks.auth) {
339 r = context->callbacks.auth(context, description, &auth,
340 context->callbacks.authData);
341 return_if_error(r, "policyAuthCallback");
342 if (auth != NULL) {
343 authValue.size = strlen(auth);
344 memcpy(&authValue.buffer[0], auth, authValue.size);
345 }
346 SAFE_FREE(auth);
347 /* Store auth value in the ESYS object. */
348 r = Esys_TR_SetAuth(context->esys, auth_object->handle, &authValue);
349 return_if_error(r, "Set auth value.");
350
351 return TSS2_RC_SUCCESS;
352 }
353 SAFE_FREE(auth);
354 return TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN;
355 }
356
357 /** Preparation for getting a free handle after a start handle number.
358 *
359 * @param[in] fctx The FAPI_CONTEXT.
360 * @param[in] handle The start value for handle search.
361 *
362 * @retval TSS2_RC_SUCCESS on success.
363 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
364 */
365 TSS2_RC
366 ifapi_get_free_handle_async(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle)
367 {
368 TSS2_RC r = Esys_GetCapability_Async(fctx->esys,
369 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
370 TPM2_CAP_HANDLES, *handle, 1);
371 return_if_error(r, "GetCapability");
372 return r;
373 }
374
375 /** Execution of get capability until a free handle is found.
376 *
377 * The get capability method is called until a free handle is found
378 * or the max number of trials passe to the function is exeeded.
379 *
380 * @param[in] fctx The FAPI_CONTEXT.
381 * @param[out] handle The free handle.
382 * @param[in] max The maximal number of trials.
383 *
384 * @retval TSS2_RC_SUCCESS on success.
385 * @retval TSS2_FAPI_RC_NV_TOO_SMALL if too many NV handles are defined.
386 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
387 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
388 * this function needs to be called again.
389 */
390 TSS2_RC
391 ifapi_get_free_handle_finish(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle,
392 TPM2_HANDLE max)
393 {
394 TPMI_YES_NO moreData;
395 TPMS_CAPABILITY_DATA *capabilityData = NULL;
396 TSS2_RC r = Esys_GetCapability_Finish(fctx->esys,
397 &moreData, &capabilityData);
398
399 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
400 return TSS2_FAPI_RC_TRY_AGAIN;
401
402 return_if_error(r, "GetCapability");
403
404 if (capabilityData->data.handles.count == 0 ||
405 capabilityData->data.handles.handle[0] != *handle) {
406 SAFE_FREE(capabilityData);
407 return TSS2_RC_SUCCESS;
408 }
409 SAFE_FREE(capabilityData);
410 *handle += 1;
411 if (*handle > max) {
412 return_error(TSS2_FAPI_RC_NV_TOO_SMALL, "No NV index free.");
413 }
414
415 r = ifapi_get_free_handle_async(fctx, handle);
416 return_if_error(r, "GetCapability");
417
418 return TSS2_FAPI_RC_TRY_AGAIN;
419 }
420
421 /** Create a linked list of directories in the key store.
422 *
423 * If the absolute path in key store is not defined the list will
424 * be extended if possible.
425 *
426 * @param[out] keystore The used keystore.
427 * @param[in] ipath The implicit pathname, which might be extended.
428 * @param[out] The linked list of directories in the explicit pathname.
429 *
430 * @retval TSS2_RC_SUCCESS If the keystore can be initialized.
431 * @retval TSS2_FAPI_RC_IO_ERROR If the user part of the keystore can't be
432 * initialized.
433 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated.
434 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
435 * the function.
436 */
437 static TSS2_RC
438 get_explicit_key_path(
439 IFAPI_KEYSTORE *keystore,
440 const char *ipath,
441 NODE_STR_T **result)
442 {
443 NODE_STR_T *list_node1 = NULL;
444 NODE_STR_T *list_node = NULL;
445
446 /* Extend the first part of the list if necessary. */
447 TSS2_RC r = init_explicit_key_path(keystore->defaultprofile, ipath,
448 &list_node1, &list_node, result);
449 goto_if_error(r, "init_explicit_key_path", error);
450
451 /* Extend the list with the tail of the initial unmodified list. */
452 while (list_node != NULL) {
453 if (!add_string_to_list(*result, list_node->str)) {
454 LOG_ERROR("Out of memory");
455 r = TSS2_FAPI_RC_MEMORY;
456 goto error;
457 }
458 list_node = list_node->next;
459 }
460 free_string_list(list_node1);
461 return TSS2_RC_SUCCESS;
462
463 error:
464 if (*result)
465 free_string_list(*result);
466 if (list_node1)
467 free_string_list(list_node1);
468 return r;
469 }
470
471 /** Prepare the creation of a primary key.
472 *
473 * Depending on the parameters the creation of an endorsement or storage root key
474 * will be prepared.
475 *
476 * @param[in] context The FAPI_CONTEXT.
477 * @param[in] ktype The type of key TSS2_EK or TSS2_SRK.
478 * @retval TSS2_RC_SUCCESS on success.
479 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
480 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
481 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
482 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
483 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
484 * this function needs to be called again.
485 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
486 * operation already pending.
487 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
488 * object store.
489 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
490 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
491 * during authorization.
492 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
493 */
494 TSS2_RC
495 ifapi_init_primary_async(FAPI_CONTEXT *context, TSS2_KEY_TYPE ktype)
496 {
497 TSS2_RC r;
498 IFAPI_OBJECT *hierarchy;
499 hierarchy = &context->cmd.Provision.hierarchy;
500 TPMS_POLICY *policy;
501
502 if (ktype == TSS2_EK) {
503 /* Values set according to EK credential profile. */
504 if (context->cmd.Provision.public_templ.public.publicArea.type == TPM2_ALG_RSA) {
505 context->cmd.Provision.public_templ.public.publicArea.unique.rsa.size = 256;
506 } else if (context->cmd.Provision.public_templ.public.publicArea.type == TPM2_ALG_ECC) {
507 context->cmd.Provision.public_templ.public.publicArea.unique.ecc.x.size = 32;
508 context->cmd.Provision.public_templ.public.publicArea.unique.ecc.y.size = 32;
509 }
510 ifapi_init_hierarchy_object(hierarchy, ESYS_TR_RH_ENDORSEMENT);
511 policy = context->profiles.default_profile.ek_policy;
512 } else if (ktype == TSS2_SRK) {
513 policy = context->profiles.default_profile.srk_policy;
514 ifapi_init_hierarchy_object(hierarchy, ESYS_TR_RH_OWNER);
515 } else {
516 return_error(TSS2_FAPI_RC_BAD_VALUE,
517 "Invalid key type. Only EK or SRK allowed");
518 }
519
520 if (policy) {
521 /* Duplicate policy to prevent profile policy from cleanup. */
522 policy = ifapi_copy_policy(policy);
523 return_if_null(policy, "Out of memory.", TSS2_FAPI_RC_MEMORY);
524
525 r = ifapi_calculate_tree(context, NULL, /**< no path needed */
526 policy,
527 context->profiles.default_profile.nameAlg,
528 &context->cmd.Provision.digest_idx,
529 &context->cmd.Provision.hash_size);
530 if (r) {
531 LOG_ERROR("Policy calculation");
532 free(policy);
533 return r;
534 }
535
536 context->cmd.Provision.public_templ.public.publicArea.authPolicy.size =
537 context->cmd.Provision.hash_size;
538 memcpy(&context->cmd.Provision.public_templ.public.publicArea.authPolicy.buffer[0],
539 &policy->policyDigests.digests[context->policy.digest_idx].digest,
540 context->cmd.Provision.hash_size);
541 }
542 context->createPrimary.pkey_object.policy = policy;
543
544 memset(&context->cmd.Provision.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
545 memset(&context->cmd.Provision.outsideInfo, 0, sizeof(TPM2B_DATA));
546 memset(&context->cmd.Provision.creationPCR, 0, sizeof(TPML_PCR_SELECTION));
547
548 r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
549 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
550 &context->cmd.Provision.inSensitive,
551 &context->cmd.Provision.public_templ.public,
552 &context->cmd.Provision.outsideInfo,
553 &context->cmd.Provision.creationPCR);
554 return r;
555 }
556
557 /** Finalize the creation of a primary key.
558 *
559 * Depending on the parameters the creation of an endorsement key or a storage root key
560 * will be finalized. The created object with the all information needed by FAPI will
561 * be stored in the FAPI context.
562 *
563 * @param[in] context The FAPI_CONTEXT.
564 * @param[in] ktype The type of key TSS2_EK or TSS2_SRK.
565 *
566 * @retval TSS2_RC_SUCCESS on success.
567 * @retval TSS2_FAPI_RC_TRY_AGAIN if the execution cannot be completed.
568 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
569 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
570 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
571 * is not set.
572 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
573 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
574 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
575 */
576 TSS2_RC
577 ifapi_init_primary_finish(FAPI_CONTEXT *context, TSS2_KEY_TYPE ktype)
578 {
579 TSS2_RC r;
580 ESYS_TR primaryHandle;
581 IFAPI_OBJECT *hierarchy;
582 TPM2B_PUBLIC *outPublic = NULL;
583 TPM2B_CREATION_DATA *creationData = NULL;
584 TPM2B_DIGEST *creationHash = NULL;
585 TPMT_TK_CREATION *creationTicket = NULL;
586 IFAPI_KEY *pkey = &context->createPrimary.pkey_object.misc.key;
587 NODE_STR_T *k_sub_path = NULL;
588
589 hierarchy = &context->cmd.Provision.hierarchy;
590
591 r = Esys_CreatePrimary_Finish(context->esys,
592 &primaryHandle, &outPublic, &creationData, &creationHash,
593 &creationTicket);
594 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
595 return TSS2_FAPI_RC_TRY_AGAIN;
596
597 /* Retry with authorization callback after trial with null auth */
598 if ((((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH))
599 && (context->state == PROVISION_AUTH_EK_NO_AUTH_SENT ||
600 context->state == PROVISION_AUTH_SRK_NO_AUTH_SENT)) {
601 r = ifapi_set_auth(context, hierarchy, "CreatePrimary");
602 goto_if_error_reset_state(r, "CreatePrimary", error_cleanup);
603
604 r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
605 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
606 &context->cmd.Provision.inSensitive,
607 &context->cmd.Provision.public,
608 &context->cmd.Provision.outsideInfo,
609 &context->cmd.Provision.creationPCR);
610 goto_if_error_reset_state(r, "CreatePrimary", error_cleanup);
611
612 if (ktype == TSS2_EK)
613 context->state = PROVISION_AUTH_EK_AUTH_SENT;
614 else
615 context->state = PROVISION_AUTH_SRK_AUTH_SENT;
616 return TSS2_FAPI_RC_TRY_AGAIN;
617
618 } else {
619 goto_if_error_reset_state(r, "FAPI Provision", error_cleanup);
620 }
621 /* Set EK or SRK handle in context. */
622 if (ktype == TSS2_EK) {
623 context->ek_handle = primaryHandle;
624 } else if (ktype == TSS2_SRK) {
625 context->srk_handle = primaryHandle;
626 } else {
627 return_error(TSS2_FAPI_RC_BAD_VALUE,
628 "Invalid key type. Only EK or SRK allowed");
629 }
630
631 /* Prepare serialization of pkey to key store. */
632
633 SAFE_FREE(pkey->serialization.buffer);
634 r = Esys_TR_Serialize(context->esys, primaryHandle, &pkey->serialization.buffer,
635 &pkey->serialization.size);
636 goto_if_error(r, "Error serialize esys object", error_cleanup);
637
638 r = ifapi_get_name(&outPublic->publicArea, &pkey->name);
639 goto_if_error(r, "Get primary name", error_cleanup);
640
641 pkey->public = *outPublic;
642 pkey->policyInstance = NULL;
643 pkey->creationData = *creationData;
644 pkey->creationTicket = *creationTicket;
645 pkey->description = NULL;
646 pkey->certificate = NULL;
647
648 /* Cleanup unused information */
649 SAFE_FREE(outPublic);
650 SAFE_FREE(creationData);
651 SAFE_FREE(creationHash);
652 SAFE_FREE(creationTicket);
653
654 if (pkey->public.publicArea.type == TPM2_ALG_RSA)
655 pkey->signing_scheme = context->profiles.default_profile.rsa_signing_scheme;
656 else
657 pkey->signing_scheme = context->profiles.default_profile.ecc_signing_scheme;
658 context->createPrimary.pkey_object.handle = primaryHandle;
659 SAFE_FREE(pkey->serialization.buffer);
660 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
661 return TSS2_RC_SUCCESS;
662
663 error_cleanup:
664 free_string_list(k_sub_path);
665 SAFE_FREE(pkey->serialization.buffer);
666 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
667 return r;
668 }
669
670 /** Prepare the loading of a primary key from key store.
671 *
672 * The asynchronous loading or the key from keystore will be prepared and
673 * the path will be stored in the FAPI context.
674 *
675 * @param[in] context The FAPI_CONTEXT.
676 * @param[in] path The FAPI path of the primary key.
677 *
678 * @retval TSS2_RC_SUCCESS on success.
679 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
680 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error was encountered.
681 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist.
682 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
683 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
684 */
685 TSS2_RC
686 ifapi_load_primary_async(FAPI_CONTEXT *context, char *path)
687 {
688
689 TSS2_RC r;
690
691 memset(&context->createPrimary.pkey_object, 0, sizeof(IFAPI_OBJECT));
692 context->createPrimary.path = path;
693 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
694 return_if_error2(r, "Could not open: %s", path);
695 context->primary_state = PRIMARY_READ_KEY;
696 return TSS2_RC_SUCCESS;
697
698 }
699
700 /** State machine to finalize the loading of a primary key from key store.
701 *
702 * The asynchronous loading or the key from keystore will be finalized.
703 * Afterwards the hierarchy object, which will be used for authorization will
704 * be loaded and the ESAPI functions for primary generation will be called
705 * if the primary is not persistent.
706 *
707 * @param[in] context The FAPI_CONTEXT.
708 * @param[out] handle The object handle of the primary key.
709 *
710 * @retval TSS2_RC_SUCCESS on success.
711 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
712 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the hierarchy file does not exist.
713 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error was encountered.
714 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
715 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
716 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
717 * this function needs to be called again.
718 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
719 * operation already pending.
720 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
721 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
722 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
723 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
724 * is not set.
725 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
726 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
727 * was not successful.
728 */
729 TSS2_RC
730 ifapi_load_primary_finish(FAPI_CONTEXT *context, ESYS_TR *handle)
731 {
732 TSS2_RC r;
733 IFAPI_OBJECT *hierarchy = &context->createPrimary.hierarchy;
734
735 TPM2B_PUBLIC *outPublic = NULL;
736 TPM2B_CREATION_DATA *creationData = NULL;
737 TPM2B_DIGEST *creationHash = NULL;
738 TPMT_TK_CREATION *creationTicket = NULL;
739 IFAPI_OBJECT *pkey_object = &context->createPrimary.pkey_object;
740 IFAPI_KEY *pkey = &context->createPrimary.pkey_object.misc.key;
741 ESYS_TR auth_session;
742
743 LOG_TRACE("call");
744
745 switch (context->primary_state) {
746 statecase(context->primary_state, PRIMARY_READ_KEY);
747 /* Read the primary key from keystore. */
748 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
749 pkey_object);
750 return_try_again(r);
751 return_if_error(r, "read_finish failed");
752
753 r = ifapi_initialize_object(context->esys, pkey_object);
754 goto_if_error_reset_state(r, "Initialize key object", error_cleanup);
755
756 /* Check whether a persistent key was loaded.
757 In this case the handle has already been set. */
758 if (pkey_object->handle != ESYS_TR_NONE) {
759 if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
760 context->ek_persistent = true;
761 } else {
762 context->srk_persistent = true;
763 }
764 /* Persistent handle will be used. */
765 *handle = pkey_object->handle;
766 break;
767 } else {
768 if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
769 context->ek_persistent = false;
770 } else {
771 context->srk_persistent = false;
772 }
773 }
774 fallthrough;
775
776 statecase(context->primary_state, PRIMARY_READ_HIERARCHY);
777 /* The hierarchy object ussed for auth_session will be loaded from key store. */
778 if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
779 r = ifapi_keystore_load_async(&context->keystore, &context->io, "/HE");
780 return_if_error2(r, "Could not open hierarchy /HE");
781 } else {
782 r = ifapi_keystore_load_async(&context->keystore, &context->io, "/HS");
783 return_if_error2(r, "Could not open hierarchy /HS");
784 }
785 fallthrough;
786
787 statecase(context->primary_state, PRIMARY_READ_HIERARCHY_FINISH);
788 r = ifapi_keystore_load_finish(&context->keystore, &context->io, hierarchy);
789 return_try_again(r);
790 return_if_error(r, "read_finish failed");
791
792 r = ifapi_initialize_object(context->esys, hierarchy);
793 goto_if_error_reset_state(r, "Initialize hierarchy object", error_cleanup);
794
795 if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
796 hierarchy->handle = ESYS_TR_RH_ENDORSEMENT;
797 } else {
798 hierarchy->handle = ESYS_TR_RH_OWNER;
799 }
800 fallthrough;
801
802 statecase(context->primary_state, PRIMARY_AUTHORIZE_HIERARCHY);
803 /* The asynchronous authorization of the hierarchy needed for primary. */
804 r = ifapi_authorize_object(context, hierarchy, &auth_session);
805 FAPI_SYNC(r, "Authorize hierarchy.", error_cleanup);
806
807 memset(&context->createPrimary.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
808 memset(&context->createPrimary.outsideInfo, 0, sizeof(TPM2B_DATA));
809 memset(&context->createPrimary.creationPCR, 0, sizeof(TPML_PCR_SELECTION));
810
811 /* Prepare primary creation. */
812 r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
813 auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
814 &context->createPrimary.inSensitive,
815 &pkey->public,
816 &context->createPrimary.outsideInfo,
817 &context->createPrimary.creationPCR);
818 return_if_error(r, "CreatePrimary");
819 fallthrough;
820
821 statecase(context->primary_state, PRIMARY_HAUTH_SENT);
822 if (context->createPrimary.handle) {
823 *handle = context->createPrimary.handle;
824 context->primary_state = PRIMARY_CREATED;
825 return TSS2_FAPI_RC_TRY_AGAIN;
826 } else {
827 r = Esys_CreatePrimary_Finish(context->esys,
828 &pkey_object->handle, &outPublic,
829 &creationData, &creationHash,
830 &creationTicket);
831 return_try_again(r);
832 goto_if_error_reset_state(r, "FAPI regenerate primary", error_cleanup);
833 }
834 *handle = pkey_object->handle;
835 context->primary_state = PRIMARY_INIT;
836 break;
837
838 statecasedefault(context->primary_state);
839 }
840 SAFE_FREE(outPublic);
841 SAFE_FREE(creationData);
842 SAFE_FREE(creationHash);
843 SAFE_FREE(creationTicket);
844 ifapi_cleanup_ifapi_object(&context->createPrimary.hierarchy);
845 return TSS2_RC_SUCCESS;
846
847 error_cleanup:
848 SAFE_FREE(outPublic);
849 SAFE_FREE(creationData);
850 SAFE_FREE(creationHash);
851 SAFE_FREE(creationTicket);
852 ifapi_cleanup_ifapi_object(&context->createPrimary.hierarchy);
853 ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
854 return r;
855 }
856
857 /** Prepare session for FAPI command execution.
858 *
859 * It will be checked whether the context of FAPI and ESAPI is initialized
860 * and whether no other FAPI command session is running.
861 * Also some handle variables in the context are initialized.
862 *
863 * @param[in] context The FAPI_CONTEXT.
864 *
865 * @retval TSS2_RC_SUCCESS on success.
866 * @retval TSS2_FAPI_RC_BAD_REFERENCE if the context is not initialized.
867 * @retval TSS2_FAPI_RC_BAD_SEQUENCE If a FAPI command session is active.
868 * @retval TSS2_FAPI_RC_NO_TPM if the ESAPI context is not initialized.
869 */
870 TSS2_RC
871 ifapi_session_init(FAPI_CONTEXT *context)
872 {
873 LOG_TRACE("call");
874 return_if_null(context, "No context", TSS2_FAPI_RC_BAD_REFERENCE);
875
876 return_if_null(context->esys, "No context", TSS2_FAPI_RC_NO_TPM);
877
878 if (context->state != _FAPI_STATE_INIT) {
879 return_error(TSS2_FAPI_RC_BAD_SEQUENCE, "Invalid State");
880 }
881
882 context->session1 = ESYS_TR_NONE;
883 context->session2 = ESYS_TR_NONE;
884 context->policy.session = ESYS_TR_NONE;
885 context->srk_handle = ESYS_TR_NONE;
886 return TSS2_RC_SUCCESS;
887 }
888
889 /** Prepare session for FAPI command execution without TPM.
890 *
891 * It will be checked whether the context of FAPI is initialized
892 * and whether no other FAPI command session is running.
893 * Also some handle variables in the context are initialized.
894 *
895 * @param[in] context The FAPI_CONTEXT.
896 *
897 * @retval TSS2_RC_SUCCESS on success.
898 * @retval TSS2_FAPI_RC_BAD_REFERENCE if the context is not initialized.
899 * @retval TSS2_FAPI_RC_BAD_SEQUENCE If a FAPI command session is active.
900 */
901 TSS2_RC
902 ifapi_non_tpm_mode_init(FAPI_CONTEXT *context)
903 {
904 LOG_TRACE("call");
905 return_if_null(context, "No context", TSS2_FAPI_RC_BAD_REFERENCE);
906
907 if (context->state != _FAPI_STATE_INIT) {
908 return_error(TSS2_FAPI_RC_BAD_SEQUENCE, "Invalid State");
909 }
910
911 context->session1 = ESYS_TR_NONE;
912 context->session2 = ESYS_TR_NONE;
913 context->policy.session = ESYS_TR_NONE;
914 context->srk_handle = ESYS_TR_NONE;
915 return TSS2_RC_SUCCESS;
916 }
917
918 /** Cleanup FAPI sessions in error cases.
919 *
920 * The uses sessions and the SRK (if not persistent) will be flushed
921 * non asynchronous in error cases.
922 *
923 * @param[in,out] context The FAPI_CONTEXT.
924 */
925 void
926 ifapi_session_clean(FAPI_CONTEXT *context)
927 {
928 if (context->session1 != ESYS_TR_NONE) {
929 if (Esys_FlushContext(context->esys, context->session1) != TSS2_RC_SUCCESS) {
930 LOG_ERROR("Cleanup session failed.");
931 }
932 context->session1 = ESYS_TR_NONE;
933 }
934 if (context->session2 != ESYS_TR_NONE) {
935 if (Esys_FlushContext(context->esys, context->session2) != TSS2_RC_SUCCESS) {
936 LOG_ERROR("Cleanup session failed.");
937 context->session2 = ESYS_TR_NONE;
938 }
939 }
940 if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
941 if (Esys_FlushContext(context->esys, context->srk_handle) != TSS2_RC_SUCCESS) {
942 LOG_ERROR("Cleanup Policy Session failed.");
943 }
944 context->srk_handle = ESYS_TR_NONE;
945 }
946 context->srk_persistent = false;
947 }
948
949 /** State machine for asynchronous cleanup of a FAPI session.
950 *
951 * Used sessions and the SRK will be flushed.
952 *
953 * @param[in] context The FAPI_CONTEXT storing the used handles.
954 *
955 * @retval TSS2_RC_SUCCESS on success.
956 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
957 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
958 * this function needs to be called again.
959 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
960 * operation already pending.
961 */
962 TSS2_RC
963 ifapi_cleanup_session(FAPI_CONTEXT *context)
964 {
965 TSS2_RC r;
966
967 switch (context->cleanup_state) {
968 statecase(context->cleanup_state, CLEANUP_INIT);
969 if (context->session1 != ESYS_TR_NONE) {
970 r = Esys_FlushContext_Async(context->esys, context->session1);
971 try_again_or_error(r, "Flush session.");
972 }
973 fallthrough;
974
975 statecase(context->cleanup_state, CLEANUP_SESSION1);
976 if (context->session1 != ESYS_TR_NONE) {
977 r = Esys_FlushContext_Finish(context->esys);
978 try_again_or_error(r, "Flush session.");
979 }
980 context->session1 = ESYS_TR_NONE;
981
982 if (context->session2 != ESYS_TR_NONE) {
983 r = Esys_FlushContext_Async(context->esys, context->session2);
984 try_again_or_error(r, "Flush session.");
985 }
986 fallthrough;
987
988 statecase(context->cleanup_state, CLEANUP_SESSION2);
989 if (context->session2 != ESYS_TR_NONE) {
990 r = Esys_FlushContext_Finish(context->esys);
991 try_again_or_error(r, "Flush session.");
992 }
993 context->session2 = ESYS_TR_NONE;
994
995 if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
996 r = Esys_FlushContext_Async(context->esys, context->srk_handle);
997 try_again_or_error(r, "Flush SRK.");
998 }
999 fallthrough;
1000
1001 statecase(context->cleanup_state, CLEANUP_SRK);
1002 if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
1003 r = Esys_FlushContext_Finish(context->esys);
1004 try_again_or_error(r, "Flush SRK.");
1005
1006 context->srk_handle = ESYS_TR_NONE;
1007 context->srk_persistent = false;
1008 }
1009 context->cleanup_state = CLEANUP_INIT;
1010 return TSS2_RC_SUCCESS;
1011
1012 statecasedefault(context->state);
1013 }
1014 }
1015
1016 /** Cleanup primary keys in error cases (non asynchronous).
1017 *
1018 * @param[in] context The FAPI_CONTEXT storing the used handles.
1019 *
1020 * @retval TSS2_RC_SUCCESS on success.
1021 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1022 */
1023 void
1024 ifapi_primary_clean(FAPI_CONTEXT *context)
1025 {
1026 if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
1027 if (Esys_FlushContext(context->esys, context->srk_handle) != TSS2_RC_SUCCESS) {
1028 LOG_ERROR("Cleanup session failed.");
1029 }
1030 context->srk_handle = ESYS_TR_NONE;
1031 }
1032 if (!context->ek_persistent && context->ek_handle != ESYS_TR_NONE) {
1033 if (Esys_FlushContext(context->esys, context->ek_handle) != TSS2_RC_SUCCESS) {
1034 LOG_ERROR("Cleanup EK failed.");
1035 }
1036 context->ek_handle = ESYS_TR_NONE;
1037 }
1038 context->srk_persistent = false;
1039 }
1040
1041 /** Prepare the session creation of a FAPI command.
1042 *
1043 * The initial state of the state machine for session creation will be determined.
1044 * Depending of the session_flags creation of a primary for the encryption of
1045 * the session secret can be adjusted.
1046 * The session passed session attributes will be used for the ESAPI command
1047 * Esys_TRSess_SetAttributes.
1048 *
1049 * @param[in] context The FAPI_CONTEXT storing the used handles.
1050 * @param[in] session_flags The flags to adjust used session and encryption
1051 * key. With IFAPI_SESSION1 and IFAPI_SESSION2 the session creation
1052 * for sesion1 and session2 can be activated, IFAPI_SESSION_GENEK
1053 * triggers the creation of the primary for session secret encryption.
1054 * @param[in] attribute_flags1 The attributes used for session1.
1055 * @param[in] attribute_flags2 The attributes used for session2.
1056 *
1057 * @retval TSS2_RC_SUCCESS on success.
1058 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the hierarchy file or the primary key file
1059 * does not exist.
1060 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
1061 * of the primary.
1062 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1063 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1064 * the function.
1065 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1066 * object store.
1067 */
1068 TSS2_RC
1069 ifapi_get_sessions_async(FAPI_CONTEXT *context,
1070 IFAPI_SESSION_TYPE session_flags,
1071 TPMA_SESSION attribute_flags1,
1072 TPMA_SESSION attribute_flags2)
1073 {
1074 TSS2_RC r;
1075
1076 LOG_TRACE("call");
1077 context->session_flags = session_flags;
1078 context->session1_attribute_flags = attribute_flags1;
1079 context->session2_attribute_flags = attribute_flags2;
1080 char *file = NULL;
1081
1082 if (!(session_flags & IFAPI_SESSION_GENEK)) {
1083 context->srk_handle = ESYS_TR_NONE;
1084 context->session_state = SESSION_CREATE_SESSION;
1085 return TSS2_RC_SUCCESS;
1086 }
1087
1088 context->primary_state = PRIMARY_INIT;
1089 r = ifapi_asprintf(&file, "%s/%s", context->config.profile_name,
1090 IFAPI_SRK_KEY_PATH);
1091 goto_if_error(r, "Error ifapi_asprintf", error_cleanup);
1092
1093 r = ifapi_load_primary_async(context, file);
1094 return_if_error_reset_state(r, "Load EK");
1095 free(file);
1096
1097 context->session_state = SESSION_WAIT_FOR_PRIMARY;
1098 return TSS2_RC_SUCCESS;
1099
1100 error_cleanup:
1101 SAFE_FREE(file);
1102 return r;
1103 }
1104
1105 /** State machine for the session creation of a FAPI command.
1106 *
1107 * The sessions needed for a FAPI command will be created. If needed also the
1108 * primary key for session encryption will be created.
1109 *
1110 * @param[in] context The FAPI_CONTEXT storing the used handles.
1111 * @param[in] profile The FAPI profile will be used to adjust session parameters.
1112 * @param[in] hash_alg The hash algorithm used for the session.
1113 *
1114 * @retval TSS2_RC_SUCCESS on success.
1115 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error was encountered.
1116 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
1117 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1118 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1119 * this function needs to be called again.
1120 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1121 * operation already pending.
1122 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1123 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1124 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1125 * the function.
1126 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1127 * during authorization.
1128 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1129 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1130 * is not set.
1131 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1132 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
1133 * was not successful.
1134 */
1135 TSS2_RC
1136 ifapi_get_sessions_finish(
1137 FAPI_CONTEXT *context,
1138 const IFAPI_PROFILE *profile,
1139 TPMI_ALG_HASH hash_alg)
1140 {
1141 TSS2_RC r;
1142
1143 switch (context->session_state) {
1144 statecase(context->session_state, SESSION_WAIT_FOR_PRIMARY);
1145 LOG_TRACE("**STATE** SESSION_WAIT_FOR_PRIMARY");
1146 r = ifapi_load_primary_finish(context, &context->srk_handle);
1147 return_try_again(r);
1148 return_if_error(r, "Load primary.");
1149 fallthrough;
1150
1151 statecase(context->session_state, SESSION_CREATE_SESSION);
1152 LOG_TRACE("**STATE** SESSION_CREATE_SESSION");
1153 if (!(context->session_flags & IFAPI_SESSION1)) {
1154 LOG_TRACE("finished");
1155 return TSS2_RC_SUCCESS;
1156 }
1157
1158 /* Initializing the first session for the caller */
1159
1160 r = ifapi_get_session_async(context->esys, context->srk_handle, profile,
1161 hash_alg);
1162 return_if_error_reset_state(r, "Create FAPI session async");
1163 fallthrough;
1164
1165 statecase(context->session_state, SESSION_WAIT_FOR_SESSION1);
1166 LOG_TRACE("**STATE** SESSION_WAIT_FOR_SESSION1");
1167 r = ifapi_get_session_finish(context->esys, &context->session1,
1168 context->session1_attribute_flags);
1169 return_try_again(r);
1170 return_if_error_reset_state(r, "Create FAPI session finish");
1171
1172 if (!(context->session_flags & IFAPI_SESSION2)) {
1173 LOG_TRACE("finished");
1174 return TSS2_RC_SUCCESS;
1175 }
1176
1177 /* Initializing the second session for the caller */
1178
1179 r = ifapi_get_session_async(context->esys, context->srk_handle, profile,
1180 profile->nameAlg);
1181 return_if_error_reset_state(r, "Create FAPI session async");
1182 fallthrough;
1183
1184 statecase(context->session_state, SESSION_WAIT_FOR_SESSION2);
1185 LOG_TRACE("**STATE** SESSION_WAIT_FOR_SESSION2");
1186 r = ifapi_get_session_finish(context->esys, &context->session2,
1187 context->session2_attribute_flags);
1188 return_try_again(r);
1189
1190 return_if_error_reset_state(r, "Create FAPI session finish");
1191 break;
1192
1193 statecasedefault(context->session_state);
1194 }
1195
1196 return TSS2_RC_SUCCESS;
1197 }
1198
1199 /** Merge profile already stored in FAPI context into a NV object template.
1200 *
1201 * The defaults for NV creation which are stored in the FAPI default profile
1202 * will be merged in the passed templates default values.
1203 *
1204 * @param[in] context The FAPI_CONTEXT with the default profile.
1205 * @param[in] template The template with the default values for the NV object.
1206 *
1207 * @retval TSS2_RC_SUCCESS on success.
1208 */
1209 TSS2_RC
1210 ifapi_merge_profile_into_nv_template(
1211 FAPI_CONTEXT *context,
1212 IFAPI_NV_TEMPLATE *template)
1213 {
1214 const TPMA_NV extend_mask = TPM2_NT_EXTEND << TPMA_NV_TPM2_NT_SHIFT;
1215 const TPMA_NV counter_mask = TPM2_NT_COUNTER << TPMA_NV_TPM2_NT_SHIFT;
1216 const TPMA_NV bitfield_mask = TPM2_NT_BITS << TPMA_NV_TPM2_NT_SHIFT;
1217 const IFAPI_PROFILE *profile = &context->profiles.default_profile;
1218 size_t hash_size;
1219
1220 template->public.nameAlg = profile->nameAlg;
1221 if ((template->public.attributes & extend_mask) == extend_mask) {
1222 /* The size of the NV ram to be extended must be read from the
1223 profile */
1224 hash_size = ifapi_hash_get_digest_size(profile->nameAlg);
1225 template->public.dataSize = hash_size;
1226 } else if ((template->public.attributes & counter_mask) == counter_mask ||
1227 (template->public.attributes & bitfield_mask) == bitfield_mask) {
1228 /* For bit fields and counters only size 8 is possible */
1229 template->public.dataSize = 8;
1230 } else {
1231 /* For normal NV ram the passed size will be used. */
1232 template->public.dataSize = context->nv_cmd.numBytes;
1233 }
1234
1235 return TSS2_RC_SUCCESS;
1236 }
1237
1238 /** Merge profile already stored in FAPI context into a key template.
1239 *
1240 * The defaults for key creation which are stored in the FAPI default profile
1241 * will be merged in the passed templates default values.
1242 *
1243 * @param[in] profile The profile which will be used to adjust the template.
1244 * @param[in] template The template with the default values for the key object.
1245 *
1246 * @retval TSS2_RC_SUCCESS on success.
1247 */
1248 TSS2_RC
1249 ifapi_merge_profile_into_template(
1250 const IFAPI_PROFILE *profile,
1251 IFAPI_KEY_TEMPLATE *template)
1252 {
1253 /* Merge profile parameters */
1254 template->public.publicArea.type = profile->type;
1255 template->public.publicArea.nameAlg = profile->nameAlg;
1256 if (profile->type == TPM2_ALG_RSA) {
1257 template->public.publicArea.parameters.rsaDetail.keyBits = profile->keyBits;
1258 template->public.publicArea.parameters.rsaDetail.exponent = profile->exponent;
1259 } else if (profile->type == TPM2_ALG_ECC) {
1260 template->public.publicArea.parameters.eccDetail.curveID = profile->curveID;
1261 template->public.publicArea.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL;
1262 }
1263
1264 /* Set remaining parameters depending on key type */
1265 if (template->public.publicArea.objectAttributes & TPMA_OBJECT_RESTRICTED) {
1266 if (template->public.publicArea.objectAttributes & TPMA_OBJECT_DECRYPT) {
1267 template->public.publicArea.parameters.asymDetail.symmetric =
1268 profile->sym_parameters;
1269 } else {
1270 template->public.publicArea.parameters.asymDetail.symmetric.algorithm =
1271 TPM2_ALG_NULL;
1272 }
1273 if (profile->type == TPM2_ALG_RSA) {
1274 if (template->public.publicArea.objectAttributes & TPMA_OBJECT_SIGN_ENCRYPT) {
1275 template->public.publicArea.parameters.rsaDetail.scheme.scheme =
1276 profile->rsa_signing_scheme.scheme;
1277 memcpy(&template->public.publicArea.parameters.rsaDetail.scheme.details,
1278 &profile->rsa_signing_scheme.details, sizeof(TPMU_ASYM_SCHEME));
1279 } else {
1280 template->public.publicArea.parameters.rsaDetail.scheme.scheme = TPM2_ALG_NULL;
1281 }
1282 } else if (profile->type == TPM2_ALG_ECC) {
1283 if (template->public.publicArea.objectAttributes & TPMA_OBJECT_SIGN_ENCRYPT) {
1284 template->public.publicArea.parameters.eccDetail.scheme.scheme =
1285 profile->ecc_signing_scheme.scheme;
1286 memcpy(&template->public.publicArea.parameters.eccDetail.scheme.details,
1287 &profile->ecc_signing_scheme.details, sizeof(TPMU_ASYM_SCHEME));
1288 } else {
1289 template->public.publicArea.parameters.eccDetail.scheme.scheme = TPM2_ALG_NULL;
1290 }
1291 } else {
1292 template->public.publicArea.parameters.asymDetail.scheme.scheme = TPM2_ALG_NULL;
1293 }
1294 } else {
1295 /* Non restricted key */
1296 template->public.publicArea.parameters.asymDetail.symmetric.algorithm =
1297 TPM2_ALG_NULL;
1298 template->public.publicArea.parameters.asymDetail.scheme.scheme = TPM2_ALG_NULL;
1299 }
1300 return TSS2_RC_SUCCESS;
1301 }
1302
1303 /** Convert absolute path to FAPI path which can be used as parameter for FAPI commands.
1304 *
1305 * Function converts the absolute path to a FAPI path.
1306 *
1307 * @param[in] keystore The used keystore.
1308 * @param[out] path FAPI key path.
1309 */
1310 static void
1311 full_path_to_fapi_path(IFAPI_KEYSTORE *keystore, char *path)
1312 {
1313 unsigned int start_pos, end_pos, i;
1314 const unsigned int path_length = strlen(path);
1315 size_t keystore_length = strlen(keystore->userdir);
1316 char fapi_path_delim;
1317
1318 start_pos = 0;
1319
1320 /* Check key store part of the path */
1321 if (strncmp(&path[0], keystore->userdir, keystore_length) == 0) {
1322 start_pos = strlen(keystore->userdir);
1323 } else {
1324 keystore_length = strlen(keystore->systemdir);
1325 if (strncmp(&path[0], keystore->systemdir, keystore_length) == 0)
1326 start_pos = strlen(keystore->systemdir);
1327 }
1328 if (!start_pos)
1329 return;
1330
1331 /* Shift FAPI path to the beginning. */
1332 end_pos = path_length - start_pos;
1333 memmove(&path[0], &path[start_pos], end_pos);
1334 size_t ip = 0;
1335 size_t lp = strlen(path);
1336
1337 /* Special handling for // */
1338 while (ip < lp) {
1339 if (strncmp(&path[ip], "//", 2) == 0) {
1340 memmove(&path[ip], &path[ip + 1], lp - ip);
1341 lp -= 1;
1342 } else {
1343 ip += 1;
1344 }
1345 }
1346
1347 /* Special handling for policy path were the name of the object file
1348 is part of the path. */
1349 if (ifapi_path_type_p(path, IFAPI_POLICY_PATH))
1350 fapi_path_delim = '.';
1351 else
1352 fapi_path_delim = IFAPI_FILE_DELIM_CHAR;
1353
1354 for (i = end_pos - 1; i > 0; i--) {
1355 if (path[i] == fapi_path_delim) {
1356 path[i] = '\0';
1357 break;
1358 }
1359 }
1360 }
1361
1362 /** Asynchronous preparation for loading a key and parent keys.
1363 *
1364 * The key loading is prepared. The pathname will be extended if possible and
1365 * a linked list with the directories will be created.
1366 *
1367 * @param[in,out] context The FAPI_CONTEXT.
1368 * @param[in] keyPath the key path without the parent directories
1369 * of the key store. (e.g. HE/EK, HS/SRK/mykey)
1370 *
1371 * @retval TSS2_RC_SUCCESS If the preparation is successful.
1372 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
1373 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1374 * the function.
1375 */
1376 TSS2_RC
1377 ifapi_load_keys_async(FAPI_CONTEXT *context, char const *keyPath)
1378 {
1379 TSS2_RC r;
1380 NODE_STR_T *path_list;
1381 size_t path_length;
1382 char *fapi_key_path = NULL;
1383
1384 LOG_TRACE("Load key: %s", keyPath);
1385 fapi_key_path = strdup(keyPath);
1386 check_oom(fapi_key_path);
1387 full_path_to_fapi_path(&context->keystore, fapi_key_path);
1388 r = get_explicit_key_path(&context->keystore, fapi_key_path, &path_list);
1389 SAFE_FREE(fapi_key_path);
1390 return_if_error(r, "Compute explicit path.");
1391
1392 context->loadKey.path_list = path_list;
1393 path_length = ifapi_path_length(path_list);
1394 r = ifapi_load_key_async(context, path_length);
1395 return_if_error(r, "Load key async.");
1396
1397 return TSS2_RC_SUCCESS;
1398 }
1399
1400 /** Asynchronous finish function for loading a key.
1401 *
1402 * @param[in,out] context The FAPI_CONTEXT.
1403 * @param[in] flush_parent If false the parent of the key to be loaded
1404 * will not be flushed.
1405 * @param[out] handle The ESYS handle of the key.
1406 * @param[out] key_object The object which will be used for the
1407 * authorization of the loaded key.
1408 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1409 * this function needs to be called again.
1410 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1411 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1412 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1413 * the function.
1414 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1415 * operation already pending.
1416 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1417 * during authorization.
1418 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1419 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1420 * object store.
1421 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1422 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1423 * is not set.
1424 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1425 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
1426 * was not successful.
1427 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1428 */
1429 TSS2_RC
1430 ifapi_load_keys_finish(
1431 FAPI_CONTEXT *context,
1432 bool flush_parent,
1433 ESYS_TR *handle,
1434 IFAPI_OBJECT **key_object)
1435 {
1436 TSS2_RC r;
1437
1438 r = ifapi_load_key_finish(context, flush_parent);
1439 if (r == TSS2_FAPI_RC_TRY_AGAIN)
1440 return r;
1441
1442 return_if_error(r, "Load keys");
1443
1444 *handle = context->loadKey.auth_object.handle;
1445 /* The current authorization object is the last key loaded and
1446 will be used. */
1447 *key_object = &context->loadKey.auth_object;
1448 free_string_list(context->loadKey.path_list);
1449 return TSS2_RC_SUCCESS;
1450 }
1451
1452 /** Initialize state machine for loading a key.
1453 *
1454 * @param[in,out] context for storing all state information.
1455 * @param[in] position the position of the key in path list stored in
1456 * context->loadKey.path_list.
1457 *
1458 * @retval TSS2_RC_SUCCESS on success.
1459 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
1460 */
1461 TSS2_RC
1462 ifapi_load_key_async(FAPI_CONTEXT *context, size_t position)
1463 {
1464 context->loadKey.state = LOAD_KEY_GET_PATH;
1465 context->loadKey.position = position;
1466 context->loadKey.key_list = NULL;
1467 context->loadKey.parent_handle = ESYS_TR_NONE;
1468 // context->loadKey.auth_object = NULL;
1469
1470 return TSS2_RC_SUCCESS;
1471 }
1472
1473 /** State machine for loading a key.
1474 *
1475 * A stack with all sup keys will be created and decremented during
1476 * the loading auf all keys.
1477 * The object of the loaded key will be stored in:
1478 * context->loadKey.auth_object
1479 *
1480 * @param[in,out] context for storing all state information.
1481 * @param[in] flush_parent If flush_parent is false parent is
1482 only flushed if a new parent is available.
1483 *
1484 * @retval TSS2_RC_SUCCESS If the loading of the key was successful.
1485 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1486 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1487 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
1488 * not covered by other return codes.
1489 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
1490 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
1491 * store.
1492 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If an object needed for loading or
1493 * authentication was not found.
1494 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
1495 * not successful.
1496 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for loading
1497 * fails.
1498 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
1499 * is not defined.
1500 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1501 * this function needs to be called again.
1502 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1503 * operation already pending.
1504 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1505 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1506 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1507 */
1508 TSS2_RC
1509 ifapi_load_key_finish(FAPI_CONTEXT *context, bool flush_parent)
1510 {
1511 TSS2_RC r;
1512 NODE_STR_T *path_list = context->loadKey.path_list;
1513 size_t *position = &context->loadKey.position;
1514 IFAPI_OBJECT *key_object = NULL;
1515 IFAPI_KEY *key = NULL;
1516 ESYS_TR auth_session;
1517
1518 switch (context->loadKey.state) {
1519 statecase(context->loadKey.state, LOAD_KEY_GET_PATH);
1520 context->loadKey.key_path = NULL;
1521 /* Compute path name of key to be loaded. */
1522 r = ifapi_path_string_n(&context->loadKey.key_path, NULL, path_list, NULL,
1523 *position);
1524 return_if_error(r, "Compute key path.");
1525
1526 context->loadKey.key_object = ifapi_allocate_object(context);
1527 goto_if_null2(context->loadKey.key_object, "Allocating key", r,
1528 TSS2_FAPI_RC_MEMORY, error_cleanup);
1529
1530 goto_if_null2(context->loadKey.key_path, "Invalid path", r,
1531 TSS2_FAPI_RC_GENERAL_FAILURE,
1532 error_cleanup); /**< to avoid scan-build errors. */
1533
1534 /* Prepare key loading. */
1535 r = ifapi_keystore_load_async(&context->keystore, &context->io,
1536 context->loadKey.key_path);
1537 return_if_error2(r, "Could not open: %s", context->loadKey.key_path);
1538 fallthrough;
1539
1540 statecase(context->loadKey.state, LOAD_KEY_READ_KEY);
1541 goto_if_null2(context->loadKey.key_path, "Invalid path", r,
1542 TSS2_FAPI_RC_GENERAL_FAILURE,
1543 error_cleanup); /**< to avoid scan-build errors. */
1544
1545 key = &context->loadKey.key_object->misc.key;
1546
1547 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
1548 context->loadKey.key_object);
1549 if (r != TSS2_RC_SUCCESS) {
1550 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
1551 }
1552 return_try_again(r);
1553 return_if_error(r, "read_finish failed");
1554
1555 if (context->loadKey.key_object->objectType != IFAPI_KEY_OBJ)
1556 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "%s is no key", error_cleanup,
1557 context->loadKey.key_path);
1558
1559 r = ifapi_initialize_object(context->esys, context->loadKey.key_object);
1560 goto_if_error_reset_state(r, "Initialize key object", error_cleanup);
1561
1562 SAFE_FREE(context->loadKey.key_path);
1563 context->loadKey.handle = context->loadKey.key_object->handle;
1564 if (context->loadKey.handle != ESYS_TR_NONE) {
1565 /* Persistent key could be desearialized keys can be loaded */
1566 r = ifapi_copy_ifapi_key_object(&context->loadKey.auth_object,
1567 context->loadKey.key_object);
1568 goto_if_error(r, "Could not copy key object", error_cleanup);
1569 ifapi_cleanup_ifapi_object(context->loadKey.key_object); context->loadKey.state = LOAD_KEY_LOAD_KEY;
1570
1571 return TSS2_FAPI_RC_TRY_AGAIN;
1572 }
1573
1574 if (key->private.size == 0) {
1575 /* Create a deep copy of the primary key */
1576 ifapi_cleanup_ifapi_key(key);
1577 r = ifapi_copy_ifapi_key(key, &context->createPrimary.pkey_object.misc.key);
1578 goto_if_error(r, "Could not copy primary key", error_cleanup);
1579 context->primary_state = PRIMARY_READ_HIERARCHY;
1580 context->loadKey.state = LOAD_KEY_WAIT_FOR_PRIMARY;
1581 return TSS2_FAPI_RC_TRY_AGAIN;
1582 }
1583 IFAPI_OBJECT * copyToPush = malloc(sizeof(IFAPI_OBJECT));
1584 goto_if_null(copyToPush, "Out of memory", TSS2_FAPI_RC_MEMORY, error_cleanup);
1585 r = ifapi_copy_ifapi_key_object(copyToPush, context->loadKey.key_object);
1586 if (r) {
1587 free(copyToPush);
1588 LOG_ERROR("Could not create a copy to push");
1589 goto error_cleanup;
1590 }
1591 /* Add object to the list of keys to be loaded. */
1592 r = push_object_to_list(copyToPush, &context->loadKey.key_list);
1593 if (r) {
1594 free(copyToPush);
1595 LOG_ERROR("Out of memory");
1596 goto error_cleanup;
1597 }
1598
1599 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
1600
1601 *position -= 1;
1602 context->loadKey.state = LOAD_KEY_GET_PATH;
1603 return TSS2_FAPI_RC_TRY_AGAIN;
1604
1605 statecase(context->loadKey.state, LOAD_KEY_LOAD_KEY);
1606 if (!(context->loadKey.key_list)) {
1607 LOG_TRACE("All keys loaded.");
1608 return TSS2_RC_SUCCESS;
1609 }
1610
1611 /* if flush_parent is false parent is only flushed if a new parent
1612 is available */
1613 if (!flush_parent && context->loadKey.parent_handle != ESYS_TR_NONE) {
1614 r = Esys_FlushContext(context->esys, context->loadKey.parent_handle);
1615 goto_if_error_reset_state(r, "Flush object", error_cleanup);
1616 }
1617 fallthrough;
1618
1619 statecase(context->loadKey.state, LOAD_KEY_AUTHORIZE);
1620 key_object = context->loadKey.key_list->object;
1621 key = &key_object->misc.key;
1622 r = ifapi_authorize_object(context, &context->loadKey.auth_object, &auth_session);
1623 FAPI_SYNC(r, "Authorize key.", error_cleanup);
1624
1625 /* Store parent handle in context for usage in ChangeAuth if not persistent */
1626 context->loadKey.parent_handle = context->loadKey.handle;
1627 if (context->loadKey.auth_object.misc.key.persistent_handle)
1628 context->loadKey.parent_handle_persistent = true;
1629 else
1630 context->loadKey.parent_handle_persistent = false;
1631
1632 TPM2B_PRIVATE private;
1633
1634 private.size = key->private.size;
1635 memcpy(&private.buffer[0], key->private.buffer, key->private.size);
1636
1637 r = Esys_Load_Async(context->esys, context->loadKey.handle,
1638 auth_session,
1639 ESYS_TR_NONE, ESYS_TR_NONE,
1640 &private, &key->public);
1641 goto_if_error(r, "Load async", error_cleanup);
1642 fallthrough;
1643
1644 statecase(context->loadKey.state, LOAD_KEY_AUTH);
1645 r = Esys_Load_Finish(context->esys, &context->loadKey.handle);
1646 return_try_again(r);
1647 goto_if_error_reset_state(r, "Load", error_cleanup);
1648
1649 /* The current parent is flushed if not prohibited by flush parent */
1650 if (flush_parent && context->loadKey.auth_object.objectType == IFAPI_KEY_OBJ &&
1651 ! context->loadKey.auth_object.misc.key.persistent_handle) {
1652 r = Esys_FlushContext(context->esys, context->loadKey.auth_object.handle);
1653 goto_if_error_reset_state(r, "Flush object", error_cleanup);
1654
1655 }
1656 LOG_TRACE("New key used as auth object.");
1657 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
1658 r = ifapi_copy_ifapi_key_object(&context->loadKey.auth_object,
1659 context->loadKey.key_list->object);
1660 goto_if_error(r, "Could not copy loaded key", error_cleanup);
1661 context->loadKey.auth_object.handle = context->loadKey.handle;
1662 IFAPI_OBJECT *top_obj = context->loadKey.key_list->object;
1663 ifapi_cleanup_ifapi_object(top_obj);
1664 SAFE_FREE(context->loadKey.key_list->object);
1665 r = pop_object_from_list(context, &context->loadKey.key_list);
1666 goto_if_error_reset_state(r, "Pop key failed.", error_cleanup);
1667
1668 if (context->loadKey.key_list) {
1669 /* Object can be cleaned if it's not the last */
1670 ifapi_free_object(context, &top_obj);
1671 }
1672
1673 context->loadKey.state = LOAD_KEY_LOAD_KEY;
1674 return TSS2_FAPI_RC_TRY_AGAIN;
1675
1676 statecase(context->loadKey.state, LOAD_KEY_WAIT_FOR_PRIMARY);
1677 r = ifapi_load_primary_finish(context, &context->loadKey.handle);
1678 return_try_again(r);
1679 goto_if_error(r, "CreatePrimary", error_cleanup);
1680
1681 /* Save the primary object for authorization */
1682 r = ifapi_copy_ifapi_key_object(&context->loadKey.auth_object,
1683 &context->createPrimary.pkey_object);
1684 goto_if_error(r, "Could not copy primary key", error_cleanup);
1685
1686 if (context->loadKey.key_list) {
1687 context->loadKey.state = LOAD_KEY_LOAD_KEY;
1688 return TSS2_FAPI_RC_TRY_AGAIN;
1689 } else {
1690 LOG_TRACE("success");
1691 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
1692 ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
1693 return TSS2_RC_SUCCESS;
1694 }
1695 break;
1696
1697 statecasedefault(context->loadKey.state);
1698 }
1699
1700 error_cleanup:
1701 ifapi_free_object_list(context->loadKey.key_list);
1702 ifapi_cleanup_ifapi_object(context->loadKey.key_object);
1703 SAFE_FREE(context->loadKey.key_path);
1704 return r;
1705 }
1706
1707 /** Get the name alg corresponding to a FAPI object.
1708 *
1709 * @param[in] context The context with the default profile.
1710 * @param[in] object The object to be checked.
1711 * @retval TPMI_ALG_HASH The hash algorithm.
1712 * @retval 0 If no name alg can be assigned to the object.
1713 */
1714 static size_t
1715 get_name_alg(FAPI_CONTEXT *context, IFAPI_OBJECT *object)
1716 {
1717 switch (object->objectType) {
1718 case IFAPI_KEY_OBJ:
1719 return object->misc.key.public.publicArea.nameAlg;
1720 case IFAPI_NV_OBJ:
1721 return object->misc.nv.public.nvPublic.nameAlg;
1722 case IFAPI_HIERARCHY_OBJ:
1723 return context->profiles.default_profile.nameAlg;
1724 default:
1725 return 0;
1726 }
1727 }
1728
1729 /** Check whether policy session has to be flushed.
1730 *
1731 * Policy sessions with cleared continue session flag are not flushed in error
1732 * cases. Therefore the return code will be checked and if a policy session was
1733 * used the session will be flushed if the command was not executed successfully.
1734 *
1735 * @param[in,out] context for storing all state information.
1736 * @param[in] session the session to be checked whether flush is needed.
1737 * @param[in] r The return code of the command using the session.
1738 */
1739 void
1740 ifapi_flush_policy_session(FAPI_CONTEXT *context, ESYS_TR session, TSS2_RC r)
1741 {
1742 if (session != context->session1) {
1743 /* A policy session was used instead auf the default session. */
1744 if (r != TSS2_RC_SUCCESS) {
1745 Esys_FlushContext(context->esys, session);
1746 }
1747 }
1748 }
1749
1750 /** State machine to authorize a key, a NV object of a hierarchy.
1751 *
1752 * @param[in,out] context for storing all state information.
1753 * @param[in] object The FAPI object.
1754 * @param[out] session The session which can be used for object authorization.
1755 *
1756 * @retval TSS2_RC_SUCCESS If the authorization is successful
1757 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1758 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
1759 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
1760 * store.
1761 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
1762 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
1763 * not successful.
1764 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for the policy
1765 * execution fails.
1766 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
1767 is not defined.
1768 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1769 * this function needs to be called again.
1770 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1771 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1772 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1773 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1774 */
1775 TSS2_RC
1776 ifapi_authorize_object(FAPI_CONTEXT *context, IFAPI_OBJECT *object, ESYS_TR *session)
1777 {
1778 TSS2_RC r;
1779 TPMI_YES_NO auth_required;
1780
1781 LOG_DEBUG("Authorize object: %x", object->handle);
1782 switch (object->authorization_state) {
1783 statecase(object->authorization_state, AUTH_INIT)
1784 LOG_TRACE("**STATE** AUTH_INIT");
1785
1786 if (!policy_digest_size(object)) {
1787 /* No policy used authorization callbacks have to be called if necessary. */
1788 if (object_with_auth(object)) {
1789 r = ifapi_set_auth(context, object, "Authorize object");
1790 return_if_error(r, "Set auth value");
1791 }
1792 /* No policy session needed current fapi session can be used */
1793 if (context->session1 && context->session1 != ESYS_TR_NONE)
1794 *session = context->session1;
1795 else
1796 /* Use password session if session1 had not been created */
1797 *session = ESYS_TR_PASSWORD;
1798 break;
1799 }
1800 r = ifapi_policyutil_execute_prepare(context, get_name_alg(context, object)
1801 ,object->policy);
1802 return_if_error(r, "Prepare policy execution.");
1803
1804 /* Next state will switch from prev context to next context. */
1805 context->policy.util_current_policy = context->policy.util_current_policy->prev;
1806 object->authorization_state = AUTH_EXEC_POLICY;
1807 fallthrough;
1808
1809 statecase(object->authorization_state, AUTH_EXEC_POLICY)
1810 *session = ESYS_TR_NONE;
1811 r = ifapi_policyutil_execute(context, session);
1812 if (r == TSS2_FAPI_RC_TRY_AGAIN)
1813 return r;
1814
1815 return_if_error(r, "Execute policy.");
1816
1817 r = Esys_TRSess_GetAuthRequired(context->esys, *session,
1818 &auth_required);
1819 return_if_error(r, "GetAuthRequired");
1820
1821 /* Check whether PolicyCommand requiring authorization was executed */
1822 if (auth_required == TPM2_YES) {
1823 r = ifapi_set_auth(context, object, "Authorize object");
1824 goto_if_error(r, "Set auth value", error);
1825 }
1826 /* Clear continue session flag, so policy session will be flushed after authorization */
1827 r = Esys_TRSess_SetAttributes(context->esys, *session, 0, TPMA_SESSION_CONTINUESESSION);
1828 goto_if_error(r, "Esys_TRSess_SetAttributes", error);
1829 break;
1830
1831 general_failure(object->authorization_state)
1832 }
1833
1834 object->authorization_state = AUTH_INIT;
1835 return TSS2_RC_SUCCESS;
1836
1837 error:
1838 /* No policy call was executed session can be flushed */
1839 Esys_FlushContext(context->esys, *session);
1840 return r;
1841 }
1842
1843 /** State machine to write data to the NV ram of the TPM.
1844 *
1845 * The NV object will be read from object store and the data will be
1846 * written by one, or more than one if necessary, ESAPI calls to the NV ram of
1847 * the TPM.
1848 * The sub context nv_cmd will be prepared:
1849 * - data The buffer for the data which has to be written
1850 * - offset The current offset for writing
1851 * - numBytes The number of bytes which have to be written.
1852 *
1853 * @param[in,out] context for storing all state information.
1854 * @param[in] nvPath The fapi path of the NV object.
1855 * @param[in] param_offset The offset in the NV memory (will be stored in context).
1856 * @param[in] data The pointer to the data to be written.
1857 * @param[in] size The number of bytes to be written.
1858 *
1859 * @retval TSS2_RC_SUCCESS If data can be written.
1860 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1861 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1862 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
1863 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
1864 + not covered by other return codes.
1865 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the object
1866 * store.
1867 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND The nv object or an object needed for
1868 * authentication was not found.
1869 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
1870 * not successful.
1871 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for the
1872 * command execution fails.
1873 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
1874 * is not defined.
1875 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
1876 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1877 * this function needs to be called again.
1878 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1879 * operation already pending.
1880 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1881 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1882 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1883 */
1884 TSS2_RC
1885 ifapi_nv_write(
1886 FAPI_CONTEXT *context,
1887 char *nvPath,
1888 size_t param_offset,
1889 uint8_t const *data,
1890 size_t size)
1891 {
1892 TSS2_RC r = TSS2_RC_SUCCESS;
1893 ESYS_TR auth_index;
1894 ESYS_TR nv_index = context->nv_cmd.esys_handle;
1895 IFAPI_OBJECT *object = &context->nv_cmd.nv_object;
1896 IFAPI_OBJECT *auth_object = &context->nv_cmd.auth_object;
1897 TPM2B_MAX_NV_BUFFER *aux_data = (TPM2B_MAX_NV_BUFFER *)&context->aux_data;
1898 char *nv_file_name = NULL;
1899 ESYS_TR auth_session;
1900
1901 switch (context->nv_cmd.nv_write_state) {
1902 statecase(context->nv_cmd.nv_write_state, NV2_WRITE_INIT);
1903 memset(&context->nv_cmd.nv_object, 0, sizeof(IFAPI_OBJECT));
1904 context->nv_cmd.nvPath = nvPath;
1905 context->nv_cmd.offset = param_offset;
1906 context->nv_cmd.numBytes = size;
1907 context->nv_cmd.data = data;
1908 if (context->nv_cmd.numBytes > context->nv_buffer_max)
1909 aux_data->size = context->nv_buffer_max;
1910 else
1911 aux_data->size = context->nv_cmd.numBytes;
1912 context->nv_cmd.data_idx = 0;
1913
1914 /* Use calloc to ensure zero padding for write buffer. */
1915 context->nv_cmd.write_data = calloc(size, 1);
1916 goto_if_null2(context->nv_cmd.write_data, "Out of memory.", r,
1917 TSS2_FAPI_RC_MEMORY,
1918 error_cleanup);
1919 memcpy(context->nv_cmd.write_data, data, size);
1920 memcpy(&aux_data->buffer[0], &context->nv_cmd.data[0], aux_data->size);
1921
1922 /* Prepare reading of the key from keystore. */
1923 r = ifapi_keystore_load_async(&context->keystore, &context->io,
1924 context->nv_cmd.nvPath);
1925 return_if_error2(r, "Could not open: %s", context->nv_cmd.nvPath);
1926 fallthrough;
1927
1928 statecase(context->nv_cmd.nv_write_state, NV2_WRITE_READ);
1929 r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
1930 return_try_again(r);
1931 return_if_error(r, "read_finish failed");
1932
1933 if (object->objectType != IFAPI_NV_OBJ)
1934 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is no NV object.", error_cleanup,
1935 context->nv_cmd.nvPath);
1936
1937 r = ifapi_initialize_object(context->esys, object);
1938 goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);
1939
1940 /* Store object info in context */
1941 nv_index = context->nv_cmd.nv_object.handle;
1942 context->nv_cmd.esys_handle = nv_index;
1943 context->nv_cmd.nv_obj = object->misc.nv;
1944
1945 /* Determine the object which will be uses for authorization. */
1946 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_PPWRITE) {
1947 ifapi_init_hierarchy_object(auth_object, ESYS_TR_RH_PLATFORM);
1948 auth_index = ESYS_TR_RH_PLATFORM;
1949 } else {
1950 if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_OWNERWRITE) {
1951 ifapi_init_hierarchy_object(auth_object, ESYS_TR_RH_OWNER);
1952 auth_index = ESYS_TR_RH_OWNER;
1953 } else {
1954 auth_index = nv_index;
1955 }
1956 *auth_object = *object;
1957 }
1958 context->nv_cmd.auth_index = auth_index;
1959
1960 /* Get A session for authorizing the NV write operation. */
1961 r = ifapi_get_sessions_async(context, IFAPI_SESSION_GENEK | IFAPI_SESSION1,
1962 TPMA_SESSION_DECRYPT, 0);
1963 goto_if_error(r, "Create sessions", error_cleanup);
1964
1965 fallthrough;
1966
1967 statecase(context->nv_cmd.nv_write_state, NV2_WRITE_WAIT_FOR_SESSSION);
1968 r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
1969 object->misc.nv.public.nvPublic.nameAlg);
1970 return_try_again(r);
1971 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
1972
1973 fallthrough;
1974
1975 statecase(context->nv_cmd.nv_write_state, NV2_WRITE_AUTHORIZE);
1976 r = ifapi_authorize_object(context, auth_object, &auth_session);
1977 FAPI_SYNC(r, "Authorize NV object.", error_cleanup);
1978
1979 /* Prepare the writing to NV ram. */
1980 r = Esys_NV_Write_Async(context->esys,
1981 context->nv_cmd.auth_index,
1982 nv_index,
1983 auth_session,
1984 context->session2,
1985 ESYS_TR_NONE,
1986 aux_data,
1987 context->nv_cmd.data_idx);
1988 goto_if_error_reset_state(r, " Fapi_NvWrite_Async", error_cleanup);
1989
1990 if (!(object->misc.nv.public.nvPublic.attributes & TPMA_NV_NO_DA))
1991 context->nv_cmd.nv_write_state = NV2_WRITE_AUTH_SENT;
1992 else
1993 context->nv_cmd.nv_write_state = NV2_WRITE_NULL_AUTH_SENT;
1994
1995 context->nv_cmd.bytesRequested = aux_data->size;
1996
1997 fallthrough;
1998
1999 case NV2_WRITE_AUTH_SENT:
2000 case NV2_WRITE_NULL_AUTH_SENT:
2001 r = Esys_NV_Write_Finish(context->esys);
2002 return_try_again(r);
2003
2004 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH) {
2005 if (context->nv_cmd.nv_write_state == NV2_WRITE_NULL_AUTH_SENT) {
2006 IFAPI_OBJECT *auth_object = &context->nv_cmd.auth_object;
2007 r = ifapi_set_auth(context, auth_object, "NV Write");
2008 goto_if_error_reset_state(r, " Fapi_NvWrite_Finish", error_cleanup);
2009
2010 /* Prepare the writing to NV ram. */
2011 r = Esys_NV_Write_Async(context->esys,
2012 context->nv_cmd.auth_index,
2013 nv_index,
2014 (!context->policy.session
2015 || context->policy.session == ESYS_TR_NONE) ? context->session1 :
2016 context->policy.session,
2017 context->session2,
2018 ESYS_TR_NONE,
2019 aux_data,
2020 context->nv_cmd.data_idx);
2021 goto_if_error_reset_state(r, "FAPI NV_Write_Async", error_cleanup);
2022
2023 context->nv_cmd.nv_write_state = NV2_WRITE_AUTH_SENT;
2024 return TSS2_FAPI_RC_TRY_AGAIN;
2025 }
2026 }
2027 goto_if_error_reset_state(r, "FAPI NV_Write_Finish", error_cleanup);
2028
2029 context->nv_cmd.numBytes -= context->nv_cmd.bytesRequested;
2030
2031 if (context->nv_cmd.numBytes > 0) {
2032 /* Increment data idx with number of transmitted bytes. */
2033 context->nv_cmd.data_idx += aux_data->size;
2034 if (context->nv_cmd.numBytes > context->nv_buffer_max)
2035 aux_data->size = context->nv_buffer_max;
2036 else
2037 aux_data->size = context->nv_cmd.numBytes;
2038 memcpy(&aux_data->buffer[0],
2039 &context->nv_cmd.write_data[context->nv_cmd.data_idx],
2040 aux_data->size);
2041
2042 statecase(context->nv_cmd.nv_write_state, NV2_WRITE_AUTHORIZE2);
2043 r = ifapi_authorize_object(context, auth_object, &auth_session);
2044 FAPI_SYNC(r, "Authorize NV object.", error_cleanup);
2045
2046 /* Prepare the writing to NV ram */
2047 r = Esys_NV_Write_Async(context->esys,
2048 context->nv_cmd.auth_index,
2049 nv_index,
2050 auth_session,
2051 context->session2,
2052 ESYS_TR_NONE,
2053 aux_data,
2054 context->nv_cmd.data_idx);
2055 goto_if_error_reset_state(r, "FAPI NV_Write", error_cleanup);
2056
2057 context->nv_cmd.bytesRequested = aux_data->size;
2058 context->nv_cmd.nv_write_state = NV2_WRITE_AUTH_SENT;
2059 return TSS2_FAPI_RC_TRY_AGAIN;
2060
2061 }
2062 fallthrough;
2063
2064 statecase(context->nv_cmd.nv_write_state, NV2_WRITE_WRITE_PREPARE);
2065 /* Set written bit in keystore */
2066 context->nv_cmd.nv_object.misc.nv.public.nvPublic.attributes |= TPMA_NV_WRITTEN;
2067 /* Perform esys serialization if necessary */
2068 r = ifapi_esys_serialize_object(context->esys, &context->nv_cmd.nv_object);
2069 goto_if_error(r, "Prepare serialization", error_cleanup);
2070
2071 /* Start writing the NV object to the key store */
2072 r = ifapi_keystore_store_async(&context->keystore, &context->io,
2073 context->nv_cmd.nvPath,
2074 &context->nv_cmd.nv_object);
2075 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
2076 context->nv_cmd.nvPath);
2077 context->nv_cmd.nv_write_state = NV2_WRITE_WRITE;
2078 fallthrough;
2079
2080 statecase(context->nv_cmd.nv_write_state, NV2_WRITE_WRITE);
2081 /* Finish writing the NV object to the key store */
2082 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
2083 return_try_again(r);
2084 return_if_error_reset_state(r, "write_finish failed");
2085
2086 LOG_DEBUG("success");
2087 r = TSS2_RC_SUCCESS;
2088
2089 context->nv_cmd.nv_write_state = NV2_WRITE_INIT;
2090 break;
2091
2092 statecasedefault(context->nv_cmd.nv_write_state);
2093 }
2094
2095 error_cleanup:
2096 SAFE_FREE(nv_file_name);
2097 SAFE_FREE(context->nv_cmd.write_data);
2098 return r;
2099 }
2100
2101 /** State machine to read data from the NV ram of the TPM.
2102 *
2103 * Context nv_cmd has to be prepared before the call of this function:
2104 * - auth_index The ESAPI handle of the authorization object.
2105 * - numBytes The number of bytes which should be read.
2106 * - esys_handle The ESAPI handle of the NV object.
2107 *
2108 * @param[in,out] context for storing all state information.
2109 * @param[out] data the data fetched from TPM.
2110 * @param[in,out] size The number of bytes requested and fetched.
2111 *
2112 * @retval TSS2_RC_SUCCESS If the data was read successfully.
2113 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
2114 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2115 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
2116 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
2117 + not covered by other return codes.
2118 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the object
2119 * store.
2120 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
2121 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
2122 * not successful.
2123 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for the
2124 * execution fails.
2125 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
2126 * is not defined.
2127 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
2128 * this function needs to be called again.
2129 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2130 * operation already pending.
2131 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
2132 */
2133 TSS2_RC
2134 ifapi_nv_read(
2135 FAPI_CONTEXT *context,
2136 uint8_t **data,
2137 size_t *size)
2138 {
2139 TSS2_RC r;
2140 UINT16 aux_size;
2141 TPM2B_MAX_NV_BUFFER *aux_data;
2142 UINT16 bytesRequested = context->nv_cmd.bytesRequested;
2143 size_t *numBytes = &context->nv_cmd.numBytes;
2144 ESYS_TR nv_index = context->nv_cmd.esys_handle;
2145 IFAPI_OBJECT *auth_object = &context->nv_cmd.auth_object;
2146 ESYS_TR session;
2147
2148 switch (context->nv_cmd.nv_read_state) {
2149 statecase(context->nv_cmd.nv_read_state, NV_READ_INIT);
2150 LOG_TRACE("NV_READ_INIT");
2151 context->nv_cmd.rdata = NULL;
2152 fallthrough;
2153
2154 statecase(context->nv_cmd.nv_read_state, NV_READ_AUTHORIZE);
2155 LOG_TRACE("NV_READ_AUTHORIZE");
2156 r = ifapi_authorize_object(context, auth_object, &session);
2157 FAPI_SYNC(r, "Authorize NV object.", error_cleanup);
2158
2159 if (*numBytes > context->nv_buffer_max)
2160 aux_size = context->nv_buffer_max;
2161 else
2162 aux_size = *numBytes;
2163
2164 /* Prepare the reading from NV ram. */
2165 r = Esys_NV_Read_Async(context->esys,
2166 context->nv_cmd.auth_index,
2167 nv_index,
2168 session,
2169 ESYS_TR_NONE,
2170 ESYS_TR_NONE,
2171 aux_size,
2172 0);
2173 goto_if_error_reset_state(r, " Fapi_NvRead_Async", error_cleanup);
2174
2175 context->nv_cmd.nv_read_state = NV_READ_AUTH_SENT;
2176 context->nv_cmd.bytesRequested = aux_size;
2177
2178 return TSS2_FAPI_RC_TRY_AGAIN;
2179
2180 statecase(context->nv_cmd.nv_read_state, NV_READ_AUTH_SENT);
2181 LOG_TRACE("NV_READ_NULL_AUTH_SENT");
2182 if (context->nv_cmd.rdata == NULL) {
2183 /* Allocate the data buffer if not already initialized. */
2184 LOG_TRACE("Allocate %zu bytes", *numBytes);
2185 context->nv_cmd.rdata = malloc(*numBytes);
2186 }
2187 *data = context->nv_cmd.rdata;
2188 goto_if_null(*data, "Malloc failed", TSS2_FAPI_RC_MEMORY, error_cleanup);
2189
2190 r = Esys_NV_Read_Finish(context->esys, &aux_data);
2191
2192 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
2193 return TSS2_FAPI_RC_TRY_AGAIN;
2194
2195 goto_if_error_reset_state(r, "FAPI NV_Read_Finish", error_cleanup);
2196
2197 if (aux_data->size < bytesRequested)
2198 *numBytes = 0;
2199 else
2200 *numBytes -= aux_data->size;
2201 memcpy(*data + context->nv_cmd.data_idx, &aux_data->buffer[0],
2202 aux_data->size);
2203 context->nv_cmd.data_idx += aux_data->size;
2204 free(aux_data);
2205 if (*numBytes > 0) {
2206 statecase(context->nv_cmd.nv_read_state, NV_READ_AUTHORIZE2);
2207 r = ifapi_authorize_object(context, auth_object, &session);
2208 FAPI_SYNC(r, "Authorize NV object.", error_cleanup);
2209
2210 /* The reading of the NV data is not completed. The next
2211 reading will be prepared. */
2212 if (*numBytes > context->nv_buffer_max)
2213 aux_size = context->nv_buffer_max;
2214 else
2215 aux_size = *numBytes;
2216
2217 r = Esys_NV_Read_Async(context->esys,
2218 context->nv_cmd.auth_index,
2219 nv_index,
2220 session,
2221 ESYS_TR_NONE,
2222 ESYS_TR_NONE,
2223 aux_size,
2224 context->nv_cmd.data_idx);
2225 goto_if_error_reset_state(r, "FAPI NV_Read", error_cleanup);
2226 context->nv_cmd.bytesRequested = aux_size;
2227 context->nv_cmd.nv_read_state = NV_READ_AUTH_SENT;
2228 return TSS2_FAPI_RC_TRY_AGAIN;
2229 } else {
2230 *size = context->nv_cmd.data_idx;
2231 context->nv_cmd.nv_read_state = NV_READ_INIT;
2232 LOG_DEBUG("success");
2233 r = TSS2_RC_SUCCESS;
2234 break;
2235 }
2236 statecasedefault(context->nv_cmd.nv_read_state);
2237 }
2238
2239 error_cleanup:
2240 return r;
2241 }
2242
2243 #define min(X,Y) (X>Y)?Y:X
2244
2245 /** State machine to retrieve random data from TPM.
2246 *
2247 * If the buffer size exceeds the maximum size, several ESAPI calls are made.
2248 *
2249 * @param[in,out] context for storing all state information.
2250 * @param[in] numBytes Number of random bytes to be computed.
2251 * @param[out] data The random data.
2252 *
2253 * @retval TSS2_RC_SUCCESS If random data can be computed.
2254 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
2255 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2256 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2257 * the function.
2258 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
2259 * this function needs to be called again.
2260 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2261 * operation already pending.
2262 */
2263 TSS2_RC
2264 ifapi_get_random(FAPI_CONTEXT *context, size_t numBytes, uint8_t **data)
2265 {
2266 TSS2_RC r;
2267 TPM2B_DIGEST *aux_data = NULL;
2268
2269 switch (context->get_random_state) {
2270 statecase(context->get_random_state, GET_RANDOM_INIT);
2271 context->get_random.numBytes = numBytes;
2272 context->get_random.data = calloc(context->get_random.numBytes, 1);
2273 context->get_random.idx = 0;
2274 return_if_null(context->get_random.data, "FAPI out of memory.",
2275 TSS2_FAPI_RC_MEMORY);
2276
2277 /* Prepare the creation of random data. */
2278 r = Esys_GetRandom_Async(context->esys,
2279 context->session1,
2280 ESYS_TR_NONE, ESYS_TR_NONE,
2281 min(context->get_random.numBytes, sizeof(TPMU_HA)));
2282 goto_if_error_reset_state(r, "FAPI GetRandom", error_cleanup);
2283 fallthrough;
2284
2285 statecase(context->get_random_state, GET_RANDOM_SENT);
2286 r = Esys_GetRandom_Finish(context->esys, &aux_data);
2287 return_try_again(r);
2288 goto_if_error_reset_state(r, "FAPI GetRandom_Finish", error_cleanup);
2289
2290 if (aux_data -> size > context->get_random.numBytes) {
2291 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "TPM returned too many bytes",
2292 error_cleanup);
2293 }
2294
2295 /* Save created random data. */
2296 memcpy(context->get_random.data + context->get_random.idx, &aux_data->buffer[0],
2297 aux_data->size);
2298 context->get_random.numBytes -= aux_data->size;
2299 context->get_random.idx += aux_data->size;
2300 Esys_Free(aux_data);
2301 aux_data = NULL;
2302 if (context->get_random.numBytes > 0) {
2303
2304 /* Continue creaion of random data if needed. */
2305 r = Esys_GetRandom_Async(context->esys, context->session1, ESYS_TR_NONE,
2306 ESYS_TR_NONE, min(context->get_random.numBytes, sizeof(TPMU_HA)));
2307 goto_if_error_reset_state(r, "FAPI GetRandom", error_cleanup);
2308
2309 return TSS2_FAPI_RC_TRY_AGAIN;
2310 }
2311 break;
2312
2313 statecasedefault(context->get_random_state);
2314 }
2315
2316 *data = context->get_random.data;
2317
2318 LOG_DEBUG("success");
2319 context->get_random_state = GET_RANDOM_INIT;
2320 return TSS2_RC_SUCCESS;
2321
2322 error_cleanup:
2323 if (aux_data)
2324 Esys_Free(aux_data);
2325 context->get_random_state = GET_RANDOM_INIT;
2326 if (context->get_random.data != NULL)
2327 SAFE_FREE(context->get_random.data);
2328 return r;
2329 }
2330
2331 /** Load a key and initialize profile and session for ESAPI execution.
2332 *
2333 * This state machine prepares the session for key loading. Some
2334 * session related parameters will be taken from profile.
2335 *
2336 * @param[in,out] context The FAPI_CONTEXT.
2337 * @param[in] keyPath the key path without the parent directories
2338 * of the key store. (e.g. HE/EK, HS/SRK/mykey)
2339 * @param[out] key_object The callee allocated internal representation
2340 * of a key object.
2341 *
2342 * @retval TSS2_RC_SUCCESS If the key was loaded successfully.
2343 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
2344 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2345 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
2346 * not covered by other return codes.
2347 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
2348 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the object
2349 * store.
2350 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy or key was not found.
2351 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
2352 * not successful.
2353 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
2354 * execution fails.
2355 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
2356 is not defined.
2357 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2358 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
2359 * this function needs to be called again.
2360 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2361 * operation already pending.
2362 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
2363 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
2364 */
2365 TSS2_RC
2366 ifapi_load_key(
2367 FAPI_CONTEXT *context,
2368 char const *keyPath,
2369 IFAPI_OBJECT **key_object)
2370 {
2371 TSS2_RC r;
2372 const IFAPI_PROFILE *profile;
2373
2374 return_if_null(keyPath, "Bad reference for key path.",
2375 TSS2_FAPI_RC_BAD_REFERENCE);
2376
2377 switch (context->Key_Sign.state) {
2378 statecase(context->Key_Sign.state, SIGN_INIT);
2379 context->Key_Sign.keyPath = keyPath;
2380
2381 /* Prepare the session creation. */
2382 r = ifapi_get_sessions_async(context,
2383 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
2384 TPMA_SESSION_DECRYPT, 0);
2385 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
2386 fallthrough;
2387
2388 statecase(context->Key_Sign.state, SIGN_WAIT_FOR_SESSION);
2389 r = ifapi_profiles_get(&context->profiles, context->Key_Sign.keyPath, &profile);
2390 goto_if_error_reset_state(r, "Reading profile data", error_cleanup);
2391
2392 r = ifapi_get_sessions_finish(context, profile, profile->nameAlg);
2393 return_try_again(r);
2394 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
2395
2396 /* Prepare the key loading. */
2397 r = ifapi_load_keys_async(context, context->Key_Sign.keyPath);
2398 goto_if_error(r, "Load keys.", error_cleanup);
2399 fallthrough;
2400
2401 statecase(context->Key_Sign.state, SIGN_WAIT_FOR_KEY);
2402 r = ifapi_load_keys_finish(context, IFAPI_FLUSH_PARENT,
2403 &context->Key_Sign.handle,
2404 key_object);
2405 return_try_again(r);
2406 goto_if_error_reset_state(r, " Load key.", error_cleanup);
2407
2408 context->Key_Sign.state = SIGN_INIT;
2409 break;
2410
2411 statecasedefault(context->Key_Sign.state);
2412 }
2413
2414 error_cleanup:
2415 return r;
2416 }
2417
2418 /** State machine for signing operation.
2419 *
2420 * The key used for signing will be authorized and the signing of the passed data
2421 * will be executed.
2422 *
2423 * @param[in,out] context The FAPI_CONTEXT.
2424 * @param[in] sig_key_object The Fapi key object which will be used to
2425 * sign the passed digest.
2426 * @param[in] padding is the padding algorithm used. Possible values are RSA_SSA,
2427 * RSA_PPSS (case insensitive). padding MAY be NULL.
2428 * @param[in] digest is the data to be signed, already hashed.
2429 * digest MUST NOT be NULL.
2430 * @param[out] tpm_signature returns the signature in binary form (DER format).
2431 * tpm_signature MUST NOT be NULL (callee-allocated).
2432 * @param[out] publicKey is the public key of the signing key in PEM format.
2433 * publicKey is callee allocated and MAY be NULL.
2434 * @param[out] certificate is the certificate associated with the signing key
2435 * in PEM format. certificate MAY be NULL.
2436 *
2437 * @retval TSS2_RC_SUCCESS If the signing was successful.
2438 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
2439 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2440 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
2441 * not covered by other return codes.
2442 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
2443 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
2444 * store.
2445 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
2446 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
2447 * not successful.
2448 * @retval TSS2_FAPI_RC_BAD_TEMPLATE In a invalid policy is loaded during execution.
2449 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
2450 * execution fails.
2451 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
2452 * is not defined.
2453 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
2454 * this function needs to be called again.
2455 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2456 * operation already pending.
2457 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
2458 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2459 */
2460 TSS2_RC
2461 ifapi_key_sign(
2462 FAPI_CONTEXT *context,
2463 IFAPI_OBJECT *sig_key_object,
2464 char const *padding,
2465 TPM2B_DIGEST *digest,
2466 TPMT_SIGNATURE **tpm_signature,
2467 char **publicKey,
2468 char **certificate)
2469 {
2470 TSS2_RC r;
2471 TPMT_SIG_SCHEME sig_scheme;
2472 ESYS_TR session;
2473
2474 TPMT_TK_HASHCHECK hash_validation = {
2475 .tag = TPM2_ST_HASHCHECK,
2476 .hierarchy = TPM2_RH_OWNER,
2477 };
2478 memset(&hash_validation.digest, 0, sizeof(TPM2B_DIGEST));
2479
2480 switch (context->Key_Sign.state) {
2481 statecase(context->Key_Sign.state, SIGN_INIT);
2482 sig_key_object = context->Key_Sign.key_object;
2483
2484 r = ifapi_authorize_object(context, sig_key_object, &session);
2485 FAPI_SYNC(r, "Authorize signature key.", cleanup);
2486
2487 context->policy.session = session;
2488
2489 r = ifapi_get_sig_scheme(context, sig_key_object, padding, digest, &sig_scheme);
2490 goto_if_error(r, "Get signature scheme", cleanup);
2491
2492 /* Prepare the signing operation. */
2493 r = Esys_Sign_Async(context->esys,
2494 context->Key_Sign.handle,
2495 session,
2496 ESYS_TR_NONE, ESYS_TR_NONE,
2497 digest,
2498 &sig_scheme,
2499 &hash_validation);
2500 goto_if_error(r, "Error: Sign", cleanup);
2501 fallthrough;
2502
2503 statecase(context->Key_Sign.state, SIGN_AUTH_SENT);
2504 context->Key_Sign.signature = NULL;
2505 r = Esys_Sign_Finish(context->esys,
2506 &context->Key_Sign.signature);
2507 return_try_again(r);
2508 ifapi_flush_policy_session(context, context->policy.session, r);
2509 goto_if_error(r, "Error: Sign", cleanup);
2510
2511 /* Prepare the flushing of the signing key. */
2512 r = Esys_FlushContext_Async(context->esys, context->Key_Sign.handle);
2513 goto_if_error(r, "Error: FlushContext", cleanup);
2514 fallthrough;
2515
2516 statecase(context->Key_Sign.state, SIGN_WAIT_FOR_FLUSH);
2517 r = Esys_FlushContext_Finish(context->esys);
2518 return_try_again(r);
2519 goto_if_error(r, "Error: Sign", cleanup);
2520
2521 int pem_size;
2522 if (publicKey) {
2523 /* Convert internal key object to PEM format. */
2524 r = ifapi_pub_pem_key_from_tpm(&sig_key_object->misc.key.public,
2525 publicKey,
2526 &pem_size);
2527 goto_if_error(r, "Conversion pub key to PEM failed", cleanup);
2528 }
2529 context->Key_Sign.handle = ESYS_TR_NONE;
2530 *tpm_signature = context->Key_Sign.signature;
2531 if (certificate) {
2532 *certificate = strdup(context->Key_Sign.key_object->misc.key.certificate);
2533 goto_if_null(*certificate, "Out of memory.",
2534 TSS2_FAPI_RC_MEMORY, cleanup);
2535 }
2536 context->Key_Sign.state = SIGN_INIT;
2537 LOG_TRACE("success");
2538 r = TSS2_RC_SUCCESS;
2539 break;
2540
2541 statecasedefault(context->Key_Sign.state);
2542 }
2543
2544 cleanup:
2545 if (context->Key_Sign.handle != ESYS_TR_NONE)
2546 Esys_FlushContext(context->esys, context->Key_Sign.handle);
2547 ifapi_cleanup_ifapi_object(context->Key_Sign.key_object);
2548 return r;
2549 }
2550
2551 /** Get json encoding for FAPI object.
2552 *
2553 * A json representation which can be used for exporting of a FAPI object will
2554 * be created.
2555 *
2556 * @param[in] context The FAPI_CONTEXT.
2557 * @param[in] object The object to be serialized.
2558 * @param[out] json_string The json string created by the deserialzation
2559 * function (callee-allocated).
2560 *
2561 * @retval TSS2_RC_SUCCESS If the serialization was successful.
2562 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2563 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during
2564 * serialization.
2565 * @retval TSS2_FAPI_RC_BAD_REFERENCE If a NULL pointer was passed for
2566 * the object.
2567 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
2568 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
2569 */
2570 TSS2_RC
2571 ifapi_get_json(FAPI_CONTEXT *context, IFAPI_OBJECT *object, char **json_string)
2572 {
2573 TSS2_RC r = TSS2_RC_SUCCESS;
2574 json_object *jso = NULL;
2575
2576 /* Perform esys serialization if necessary */
2577 r = ifapi_esys_serialize_object(context->esys, object);
2578 goto_if_error(r, "Prepare serialization", cleanup);
2579
2580 r = ifapi_json_IFAPI_OBJECT_serialize(object, &jso);
2581 return_if_error(r, "Serialize duplication object");
2582
2583 *json_string = strdup(json_object_to_json_string_ext(jso,
2584 JSON_C_TO_STRING_PRETTY));
2585 goto_if_null2(*json_string, "Converting json to string", r, TSS2_FAPI_RC_MEMORY,
2586 cleanup);
2587
2588 cleanup:
2589 if (jso)
2590 json_object_put(jso);
2591 return r;
2592 }
2593
2594 /** Serialize persistent objects into buffer of keystore object.
2595 *
2596 * NV objects and persistent keys will serialized via the ESYS API to
2597 * enable reconstruction durinng loading from keystore.
2598 *
2599 * @param[in] ectx The ESAPI context.
2600 * @param[in,out] object The nv object or the key.
2601 * @retval TSS2_RC_SUCCESS if the function call was a success.
2602 */
2603 TSS2_RC
2604 ifapi_esys_serialize_object(ESYS_CONTEXT *ectx, IFAPI_OBJECT *object)
2605 {
2606 TSS2_RC r = TSS2_RC_SUCCESS;
2607 IFAPI_KEY *key_object = NULL;
2608 IFAPI_NV *nv_object;
2609
2610 switch (object->objectType) {
2611 case IFAPI_NV_OBJ:
2612 nv_object = &object->misc.nv;
2613 if (nv_object->serialization.buffer != NULL) {
2614 /* Cleanup old buffer */
2615 Fapi_Free(nv_object->serialization.buffer);
2616 nv_object->serialization.buffer = NULL;
2617 }
2618 r = Esys_TR_Serialize(ectx, object->handle,
2619 &nv_object->serialization.buffer,
2620 &nv_object->serialization.size);
2621 return_if_error(r, "Error serialize esys object");
2622 break;
2623
2624 case IFAPI_KEY_OBJ:
2625 key_object = &object->misc.key;
2626 key_object->serialization.size = 0;
2627 if (key_object->serialization.buffer != NULL) {
2628 /* Cleanup old buffer */
2629 Fapi_Free(key_object->serialization.buffer);
2630 key_object->serialization.buffer = NULL;
2631 }
2632 if (object->handle != ESYS_TR_NONE && key_object->persistent_handle) {
2633 key_object->serialization.buffer = NULL;
2634 r = Esys_TR_Serialize(ectx, object->handle,
2635 &key_object->serialization.buffer,
2636 &key_object->serialization.size);
2637 return_if_error(r, "Error serialize esys object");
2638 }
2639 break;
2640
2641 default:
2642 /* Nothing to be done */
2643 break;
2644 }
2645 return TSS2_RC_SUCCESS;
2646 }
2647
2648 /** Initialize the part of an IFAPI_OBJECT which is not serialized.
2649 *
2650 * For persistent objects the correspodning ESYS object will be created.
2651 *
2652 * @param[in,out] ectx The ESYS context.
2653 * @param[out] object the deserialzed binary object.
2654 * @retval TSS2_RC_SUCCESS if the function call was a success.
2655 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2656 */
2657 TSS2_RC
2658 ifapi_initialize_object(
2659 ESYS_CONTEXT *ectx,
2660 IFAPI_OBJECT *object)
2661 {
2662 TSS2_RC r = TSS2_RC_SUCCESS;
2663 ESYS_TR handle;
2664
2665 switch (object->objectType) {
2666 case IFAPI_NV_OBJ:
2667 if (object->misc.nv.serialization.size > 0) {
2668 r = Esys_TR_Deserialize(ectx, &object->misc.nv.serialization.buffer[0],
2669 object->misc.nv.serialization.size, &handle);
2670 goto_if_error(r, "Error dserialize esys object", cleanup);
2671 } else {
2672 handle = ESYS_TR_NONE;
2673 }
2674 object->authorization_state = AUTH_INIT;
2675 object->handle = handle;
2676 break;
2677
2678 case IFAPI_KEY_OBJ:
2679 if (object->misc.key.serialization.size > 0) {
2680 r = Esys_TR_Deserialize(ectx, &object->misc.key.serialization.buffer[0],
2681 object->misc.key.serialization.size, &handle);
2682 goto_if_error(r, "Error deserialize esys object", cleanup);
2683 } else {
2684 handle = ESYS_TR_NONE;
2685 }
2686 object->authorization_state = AUTH_INIT;
2687 object->handle = handle;
2688 break;
2689
2690 default:
2691 /* Nothing to be done */
2692 break;
2693 }
2694
2695 return r;
2696
2697 cleanup:
2698 SAFE_FREE(object->policy);
2699 return r;
2700 }
2701
2702 /** Prepare key creation with an auth value.
2703 *
2704 * The auth value will be copied int the FAPI context for later use in key creation.
2705 *
2706 * @param[in,out] context The FAPI_CONTEXT.
2707 * @param[in] keyPath the key path without the parent directories
2708 * of the key store. (e.g. HE/EK, HS/SRK/mykey)
2709 * @param[in] policyPath identifies the policy to be associated with the new key.
2710 * policyPath MAY be NULL. If policyPath is NULL then no policy will
2711 * be associated with the key.
2712 * @param[in] authValue The authentication value of the key.
2713 *
2714 * @retval TSS2_RC_SUCCESS If the preparation was successful.
2715 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS If the object with does already exist in
2716 * keystore.
2717 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2718 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2719 * the function.
2720 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2721 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
2722 * config file.
2723 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2724 * operation already pending.
2725 */
2726 TSS2_RC
2727 ifapi_key_create_prepare_auth(
2728 FAPI_CONTEXT *context,
2729 char const *keyPath,
2730 char const *policyPath,
2731 char const *authValue)
2732 {
2733 TSS2_RC r;
2734
2735 memset(&context->cmd.Key_Create.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
2736 if (authValue) {
2737 /* Copy the auth value */
2738 if (strlen(authValue) > sizeof(TPMU_HA)) {
2739 return_error(TSS2_FAPI_RC_BAD_VALUE, "Password too long.");
2740 }
2741 memcpy(&context->cmd.Key_Create.inSensitive.sensitive.userAuth.buffer,
2742 authValue, strlen(authValue));
2743 context->cmd.Key_Create.inSensitive.sensitive.userAuth.size = strlen(authValue);
2744 }
2745 context->cmd.Key_Create.inSensitive.sensitive.data.size = 0;
2746 r = ifapi_key_create_prepare(context, keyPath, policyPath);
2747 return r;
2748 }
2749
2750 /** Prepare key creation with an auth value and sensitive data.
2751 *
2752 * The auth value and the sensitive data will be copied int the FAPI context
2753 * for later use in key creation.
2754 *
2755 * @param[in,out] context The FAPI_CONTEXT.
2756 * @param[in] keyPath the key path without the parent directories
2757 * of the key store. (e.g. HE/EK, HS/SRK/mykey)
2758 * @param[in] policyPath identifies the policy to be associated with the new key.
2759 * policyPath MAY be NULL. If policyPath is NULL then no policy will
2760 * be associated with the key.
2761 * @param[in] dataSize The size of the sensitive data.
2762 * @param[in] authValue The authentication value of the key.
2763 * @param[in] data The sensitive data.
2764 *
2765 * @retval TSS2_RC_SUCCESS If the preparation was successful.
2766 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS If the object with does already exist in
2767 * keystore.
2768 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2769 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2770 * the function.
2771 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2772 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
2773 * config file.
2774 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2775 * operation already pending.
2776 */
2777 TSS2_RC
2778 ifapi_key_create_prepare_sensitive(
2779 FAPI_CONTEXT *context,
2780 char const *keyPath,
2781 char const *policyPath,
2782 size_t dataSize,
2783 char const *authValue,
2784 uint8_t const *data)
2785 {
2786 TSS2_RC r;
2787
2788 memset(&context->cmd.Key_Create.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
2789 if (dataSize > sizeof(TPMU_HA) || dataSize == 0) {
2790 return_error(TSS2_FAPI_RC_BAD_VALUE, "Data to big or equal zero.");
2791 }
2792 if (data)
2793 /* Copy the sensitive data */
2794 memcpy(&context->cmd.Key_Create.inSensitive.sensitive.data.buffer,
2795 data, dataSize);
2796 context->cmd.Key_Create.inSensitive.sensitive.data.size = dataSize;
2797 if (authValue) {
2798 /* Copy the auth value. */
2799 if (strlen(authValue) > sizeof(TPMU_HA)) {
2800 return_error(TSS2_FAPI_RC_BAD_VALUE, "Password too long.");
2801 }
2802 memcpy(&context->cmd.Key_Create.inSensitive.sensitive.userAuth.buffer,
2803 authValue, strlen(authValue));
2804 context->cmd.Key_Create.inSensitive.sensitive.userAuth.size = strlen(authValue);
2805 }
2806 r = ifapi_key_create_prepare(context, keyPath, policyPath);
2807 return r;
2808 }
2809
2810 /** Prepare key creation if possible.
2811 *
2812 * It will be checked whether the object already exists in key store and the FAPI context
2813 * will be initialized appropriate for key creation.
2814 *
2815 * @param[in,out] context The FAPI_CONTEXT.
2816 * @param[in] keyPath the key path without the parent directories
2817 * of the key store. (e.g. HE/EK, HS/SRK/mykey)
2818 * @param[in] policyPath identifies the policy to be associated with the new key.
2819 * policyPath MAY be NULL. If policyPath is NULL then no policy will
2820 * be associated with the key.
2821 *
2822 * @retval TSS2_RC_SUCCESS If the preparation was successful.
2823 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS If the object with does already exist in
2824 * keystore.
2825 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2826 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2827 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
2828 * config file.
2829 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2830 * operation already pending.
2831 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2832 * the function.
2833 */
2834 TSS2_RC
2835 ifapi_key_create_prepare(
2836 FAPI_CONTEXT *context,
2837 char const *keyPath,
2838 char const *policyPath)
2839 {
2840 TSS2_RC r;
2841 IFAPI_OBJECT *object = &context->cmd.Key_Create.object;
2842 NODE_STR_T *path_list = NULL;
2843
2844 LOG_TRACE("call");
2845 r = ifapi_session_init(context);
2846 return_if_error(r, "Initialize Key_Create");
2847
2848 /* First check whether an existing object would be overwritten */
2849 r = ifapi_keystore_check_overwrite(&context->keystore, &context->io,
2850 keyPath);
2851 return_if_error2(r, "Check overwrite %s", keyPath);
2852
2853 context->srk_handle = 0;
2854
2855 /* Clear the memory used for the the new key object */
2856 memset(&context->cmd.Key_Create.outsideInfo, 0, sizeof(TPM2B_DATA));
2857 memset(&context->cmd.Key_Create.creationPCR, 0, sizeof(TPML_PCR_SELECTION));
2858 memset(object, 0, sizeof(IFAPI_OBJECT));
2859
2860 strdup_check(context->cmd.Key_Create.policyPath, policyPath, r, error);
2861 strdup_check(context->cmd.Key_Create.keyPath, keyPath, r, error);
2862 r = get_explicit_key_path(&context->keystore, keyPath, &path_list);
2863 return_if_error(r, "Compute explicit path.");
2864
2865 context->loadKey.path_list = path_list;
2866 char *file;
2867 r = ifapi_path_string(&file, NULL, path_list, NULL);
2868 goto_if_error(r, "Compute explicit path.", error);
2869
2870 LOG_DEBUG("Explicit key path: %s", file);
2871
2872 free(file);
2873
2874 context->cmd.Key_Create.state = KEY_CREATE_INIT;
2875
2876 return TSS2_RC_SUCCESS;
2877
2878 error:
2879 free_string_list(path_list);
2880 return r;
2881 }
2882
2883 /** State machine for key creation.
2884 *
2885 * The function for the preparation of the key have to called before the state machine can
2886 * be activated. The linked list for the used directories must be available in the
2887 * FAPI context.
2888 * It will be checked whether the object already exists in key store and the FAPI context
2889 * will be initialized appropriate for key creation.
2890 *
2891 * @param[in,out] context The FAPI_CONTEXT.
2892 * @param[in] template The template which defines the key attributes and whether the
2893 * key will be persistent.
2894 *
2895 * @retval TSS2_RC_SUCCESS If the key could be generated.
2896 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
2897 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2898 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
2899 * not covered by other return codes.
2900 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
2901 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
2902 * store.
2903 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If an object needed for creation or
2904 authentication was not found.
2905 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
2906 * not successful.
2907 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for creation
2908 * fails.
2909 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
2910 * is not defined.
2911 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
2912 * this function needs to be called again.
2913 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
2914 * operation already pending.
2915 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2916 */
2917 TSS2_RC
2918 ifapi_key_create(
2919 FAPI_CONTEXT *context,
2920 IFAPI_KEY_TEMPLATE *template)
2921 {
2922 TSS2_RC r;
2923 size_t path_length;
2924 NODE_STR_T *path_list = context->loadKey.path_list;
2925 TPM2B_PUBLIC *outPublic = NULL;
2926 TPM2B_PRIVATE *outPrivate = NULL;
2927 TPM2B_CREATION_DATA *creationData = NULL;
2928 TPM2B_DIGEST *creationHash = NULL;
2929 TPMT_TK_CREATION *creationTicket = NULL;
2930 IFAPI_OBJECT *object = &context->cmd.Key_Create.object;
2931 ESYS_TR auth_session;
2932
2933 LOG_TRACE("call");
2934
2935 switch (context->cmd.Key_Create.state) {
2936 statecase(context->cmd.Key_Create.state, KEY_CREATE_INIT);
2937 context->cmd.Key_Create.public_templ = *template;
2938
2939 /* Profile name is first element of the explicit path list */
2940 char *profile_name = context->loadKey.path_list->str;
2941 r = ifapi_profiles_get(&context->profiles, profile_name, &context->cmd.Key_Create.profile);
2942 goto_if_error_reset_state(r, "Retrieving profile data", error_cleanup);
2943
2944 if (context->cmd.Key_Create.inSensitive.sensitive.data.size > 0) {
2945 /* A keyed hash object sealing sensitive data will be created */
2946 context->cmd.Key_Create.public_templ.public.publicArea.type = TPM2_ALG_KEYEDHASH;
2947 context->cmd.Key_Create.public_templ.public.publicArea.nameAlg =
2948 context->cmd.Key_Create.profile->nameAlg;
2949 context->cmd.Key_Create.public_templ.public.publicArea.parameters.keyedHashDetail.scheme.scheme =
2950 TPM2_ALG_NULL;
2951 } else {
2952 r = ifapi_merge_profile_into_template(context->cmd.Key_Create.profile,
2953 &context->cmd.Key_Create.public_templ);
2954 goto_if_error_reset_state(r, "Merge profile", error_cleanup);
2955 }
2956
2957 if (context->cmd.Key_Create.policyPath
2958 && strcmp(context->cmd.Key_Create.policyPath, "") != 0)
2959 context->cmd.Key_Create.state = KEY_CREATE_CALCULATE_POLICY;
2960 /* else jump over to KEY_CREATE_WAIT_FOR_SESSION below */
2961 /* FALLTHRU */
2962
2963 case KEY_CREATE_CALCULATE_POLICY:
2964 if (context->cmd.Key_Create.state == KEY_CREATE_CALCULATE_POLICY) {
2965 r = ifapi_calculate_tree(context, context->cmd.Key_Create.policyPath,
2966 &context->policy.policy,
2967 context->cmd.Key_Create.public_templ.public.publicArea.nameAlg,
2968 &context->policy.digest_idx,
2969 &context->policy.hash_size);
2970 return_try_again(r);
2971 goto_if_error2(r, "Calculate policy tree %s", error_cleanup,
2972 context->cmd.Key_Create.policyPath);
2973
2974 /* Store the calculated policy in the key object */
2975 object->policy = calloc(1, sizeof(TPMS_POLICY));
2976 return_if_null(object->policy, "Out of memory",
2977 TSS2_FAPI_RC_MEMORY);
2978 *(object->policy) = context->policy.policy;
2979
2980 context->cmd.Key_Create.public_templ.public.publicArea.authPolicy.size =
2981 context->policy.hash_size;
2982 memcpy(&context->cmd.Key_Create.public_templ.public.publicArea.authPolicy.buffer[0],
2983 &context->policy.policy.policyDigests.digests[context->policy.digest_idx].digest,
2984 context->policy.hash_size);
2985 }
2986 r = ifapi_get_sessions_async(context,
2987 IFAPI_SESSION_GENEK | IFAPI_SESSION1,
2988 TPMA_SESSION_DECRYPT, 0);
2989 goto_if_error_reset_state(r, "Create sessions", error_cleanup);
2990 fallthrough;
2991
2992 statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_SESSION);
2993 LOG_TRACE("KEY_CREATE_WAIT_FOR_SESSION");
2994 r = ifapi_get_sessions_finish(context, context->cmd.Key_Create.profile,
2995 context->cmd.Key_Create.profile->nameAlg);
2996 return_try_again(r);
2997 goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
2998
2999 path_length = ifapi_path_length(path_list);
3000 r = ifapi_load_key_async(context, path_length - 1);
3001 goto_if_error(r, "LoadKey async", error_cleanup);
3002 fallthrough;
3003
3004 statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_PARENT);
3005 LOG_TRACE("KEY_CREATE_WAIT_FOR_PARENT");
3006 r = ifapi_load_key_finish(context, IFAPI_FLUSH_PARENT);
3007 return_try_again(r);
3008 goto_if_error(r, "LoadKey finish", error_cleanup);
3009 fallthrough;
3010
3011 statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_AUTHORIZATION);
3012 r = ifapi_authorize_object(context, &context->loadKey.auth_object, &auth_session);
3013 FAPI_SYNC(r, "Authorize key.", error_cleanup);
3014
3015 r = Esys_Create_Async(context->esys, context->loadKey.auth_object.handle,
3016 auth_session,
3017 ESYS_TR_NONE, ESYS_TR_NONE,
3018 &context->cmd.Key_Create.inSensitive,
3019 &context->cmd.Key_Create.public_templ.public,
3020 &context->cmd.Key_Create.outsideInfo,
3021 &context->cmd.Key_Create.creationPCR);
3022 goto_if_error(r, "Create_Async", error_cleanup);
3023 fallthrough;
3024
3025 statecase(context->cmd.Key_Create.state, KEY_CREATE_AUTH_SENT);
3026 r = Esys_Create_Finish(context->esys, &outPrivate, &outPublic, &creationData,
3027 &creationHash, &creationTicket);
3028 try_again_or_error_goto(r, "Key create finish", error_cleanup);
3029
3030 /* Prepare object for serialization */
3031 object->system = context->cmd.Key_Create.public_templ.system;
3032 object->objectType = IFAPI_KEY_OBJ;
3033 object->misc.key.public = *outPublic;
3034 object->misc.key.private.size = outPrivate->size;
3035 object->misc.key.private.buffer = calloc(1, outPrivate->size);
3036 goto_if_null2( object->misc.key.private.buffer, "Out of memory.", r,
3037 TSS2_FAPI_RC_MEMORY, error_cleanup);
3038
3039 object->misc.key.private.buffer = memcpy(&object->misc.key.private.buffer[0],
3040 &outPrivate->buffer[0], outPrivate->size);
3041 object->misc.key.policyInstance = NULL;
3042 object->misc.key.creationData = *creationData;
3043 object->misc.key.creationTicket = *creationTicket;
3044 object->misc.key.description = NULL;
3045 object->misc.key.certificate = NULL;
3046 SAFE_FREE(outPrivate);
3047 SAFE_FREE(creationData);
3048 SAFE_FREE(creationTicket);
3049 SAFE_FREE(creationHash);
3050 if (context->cmd.Key_Create.inSensitive.sensitive.userAuth.size > 0)
3051 object->misc.key.with_auth = TPM2_YES;
3052 else
3053 object->misc.key.with_auth = TPM2_NO;;
3054 r = ifapi_get_name(&outPublic->publicArea, &object->misc.key.name);
3055 goto_if_error(r, "Get key name", error_cleanup);
3056
3057 if (object->misc.key.public.publicArea.type == TPM2_ALG_RSA)
3058 object->misc.key.signing_scheme = context->cmd.Key_Create.profile->rsa_signing_scheme;
3059 else
3060 object->misc.key.signing_scheme = context->cmd.Key_Create.profile->ecc_signing_scheme;
3061 SAFE_FREE(outPublic);
3062 fallthrough;
3063
3064 statecase(context->cmd.Key_Create.state, KEY_CREATE_WRITE_PREPARE);
3065 /* Perform esys serialization if necessary */
3066 r = ifapi_esys_serialize_object(context->esys, object);
3067 goto_if_error(r, "Prepare serialization", error_cleanup);
3068
3069 /* Start writing the NV object to the key store */
3070 r = ifapi_keystore_store_async(&context->keystore, &context->io,
3071 context->cmd.Key_Create.keyPath, object);
3072 goto_if_error_reset_state(r, "Could not open: %sh", error_cleanup,
3073 context->cmd.Key_Create.keyPath);
3074 ifapi_cleanup_ifapi_object(object);
3075 fallthrough;
3076
3077 statecase(context->cmd.Key_Create.state, KEY_CREATE_WRITE);
3078 /* Finish writing the key to the key store */
3079 r = ifapi_keystore_store_finish(&context->keystore, &context->io);
3080 return_try_again(r);
3081 return_if_error_reset_state(r, "write_finish failed");
3082
3083 if (context->loadKey.auth_object.misc.key.persistent_handle) {
3084 context->cmd.Key_Create.state = KEY_CREATE_INIT;
3085 r = TSS2_RC_SUCCESS;
3086 break;
3087 }
3088 /* Prepare Flushing of key used for authorization */
3089 r = Esys_FlushContext_Async(context->esys, context->loadKey.auth_object.handle);
3090 goto_if_error(r, "Flush parent", error_cleanup);
3091 fallthrough;
3092
3093 statecase(context->cmd.Key_Create.state, KEY_CREATE_FLUSH);
3094 r = Esys_FlushContext_Finish(context->esys);
3095 try_again_or_error_goto(r, "Flush context", error_cleanup);
3096 fallthrough;
3097
3098 statecase(context->cmd.Key_Create.state, KEY_CREATE_CLEANUP);
3099 r = ifapi_cleanup_session(context);
3100 try_again_or_error_goto(r, "Cleanup", error_cleanup);
3101
3102 context->cmd.Key_Create.state = KEY_CREATE_INIT;
3103 r = TSS2_RC_SUCCESS;
3104 break;
3105
3106 statecasedefault(context->cmd.Key_Create.state);
3107 }
3108 error_cleanup:
3109 free_string_list(context->loadKey.path_list);
3110 SAFE_FREE(outPublic);
3111 SAFE_FREE(outPrivate);
3112 SAFE_FREE(creationData);
3113 SAFE_FREE(creationHash);
3114 SAFE_FREE(creationTicket);
3115 SAFE_FREE(context->cmd.Key_Create.policyPath);
3116 SAFE_FREE(context->cmd.Key_Create.keyPath);
3117 ifapi_cleanup_ifapi_object(object);
3118 ifapi_session_clean(context);
3119 return r;
3120 }
3121
3122 /** Get signature scheme for key.
3123 *
3124 * If padding is passed the scheme will be derived from paddint otherwise
3125 * the scheme form object will be used.
3126 *
3127 * @param[in] context The FAPI_CONTEXT.
3128 * @param[in] object The internal FAPI object of the key.
3129 * @param[in] padding The strings RSA_SSA or RSA_PSS will be converted
3130 * into the TSS constants used for the signing scheme.
3131 * @param[in] digest The digest size will be used to determine the hashalg
3132 * for the signature scheme.
3133 * @param[out] sig_scheme The computed signature scheme.
3134 *
3135 * @retval TSS2_FAPI_RC_BAD_VALUE If the digest size is not appropriate.
3136 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3137 */
3138 TSS2_RC
3139 ifapi_get_sig_scheme(
3140 FAPI_CONTEXT *context,
3141 IFAPI_OBJECT *object,
3142 char const *padding,
3143 TPM2B_DIGEST *digest,
3144 TPMT_SIG_SCHEME *sig_scheme)
3145 {
3146 TPMI_ALG_HASH hash_alg;
3147 TSS2_RC r;
3148
3149 if (padding) {
3150 /* Get hash algorithm from digest size */
3151 r = ifapi_get_hash_alg_for_size(digest->size, &hash_alg);
3152 return_if_error2(r, "Invalid digest size.");
3153
3154 /* Use scheme object from context */
3155 if (strcasecmp("RSA_SSA", padding) == 0) {
3156 context->Key_Sign.scheme.scheme = TPM2_ALG_RSASSA;
3157 context->Key_Sign.scheme.details.rsassa.hashAlg = hash_alg;
3158 }
3159 if (strcasecmp("RSA_PSS", padding) == 0) {
3160 context->Key_Sign.scheme.scheme = TPM2_ALG_RSAPSS;
3161 context->Key_Sign.scheme.details.rsapss.hashAlg = hash_alg;
3162 }
3163 *sig_scheme = context->Key_Sign.scheme;
3164 return TSS2_RC_SUCCESS;
3165 } else {
3166 /* Use scheme defined for object */
3167 *sig_scheme = object->misc.key.signing_scheme;
3168 /* Get hash algorithm from digest size */
3169 r = ifapi_get_hash_alg_for_size(digest->size, &hash_alg);
3170 return_if_error2(r, "Invalid digest size.");
3171
3172 sig_scheme->details.any.hashAlg = hash_alg;
3173 return TSS2_RC_SUCCESS;
3174 }
3175 }
3176
3177 /** State machine for changing the hierarchy authorization.
3178 *
3179 * First it will be tried to set the auth value of the hierarchy with a
3180 * "null" authorization. If this trial is not successful it will be tried to
3181 * authorize the hierarchy via a callback.
3182 * If an not null auth value is passed with_auth is set to yes for the
3183 * object otherwise to no. So for later authorizations it will be clear
3184 * whether null authorization is possible or not.
3185 *
3186 * @param[in] context The FAPI_CONTEXT.
3187 * @param[in] handle The ESAPI handle of the hierarchy.
3188 * @param[in,out] hierarchy_object The internal FAPI representation of a
3189 * hierarchy.
3190 * @param[in] newAuthValue The new authorization for the hierarchy.
3191 *
3192 * @retval TSS2_RC_SUCCESS on success.
3193 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
3194 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
3195 * this function needs to be called again.
3196 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
3197 * operation already pending.
3198 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
3199 * is not set.
3200 */
3201 TSS2_RC
3202 ifapi_change_auth_hierarchy(
3203 FAPI_CONTEXT *context,
3204 ESYS_TR handle,
3205 IFAPI_OBJECT *hierarchy_object,
3206 TPM2B_AUTH *newAuthValue)
3207 {
3208 TSS2_RC r;
3209
3210 switch (context->hierarchy_state) {
3211 statecase(context->hierarchy_state, HIERARCHY_CHANGE_AUTH_INIT);
3212 if (newAuthValue->size > 0)
3213 hierarchy_object->misc.hierarchy.with_auth = TPM2_YES;
3214 else
3215 hierarchy_object->misc.hierarchy.with_auth = TPM2_NO;
3216 r = Esys_HierarchyChangeAuth_Async(context->esys,
3217 handle,
3218 (context->session1
3219 && context->session1 != ESYS_TR_NONE) ?
3220 context->session1 : ESYS_TR_PASSWORD,
3221 ESYS_TR_NONE, ESYS_TR_NONE,
3222 newAuthValue);
3223 return_if_error(r, "HierarchyChangeAuth");
3224 fallthrough;
3225
3226 statecase(context->hierarchy_state, HIERARCHY_CHANGE_AUTH_NULL_AUTH_SENT);
3227 r = Esys_HierarchyChangeAuth_Finish(context->esys);
3228 return_try_again(r);
3229
3230 if ((r & ~TPM2_RC_N_MASK) != TPM2_RC_BAD_AUTH) {
3231 return_if_error(r, "Hierarchy change auth.");
3232 context->hierarchy_state = HIERARCHY_CHANGE_AUTH_INIT;
3233 LOG_TRACE("success");
3234 return TSS2_RC_SUCCESS;
3235 }
3236
3237 /* Retry after NULL authorization was not successful */
3238 r = ifapi_set_auth(context, hierarchy_object, "Hierarchy object");
3239 return_if_error(r, "HierarchyChangeAuth");
3240
3241 r = Esys_HierarchyChangeAuth_Async(context->esys,
3242 handle,
3243 (context->session1
3244 && context->session1 != ESYS_TR_NONE) ?
3245 context->session1 : ESYS_TR_PASSWORD,
3246 ESYS_TR_NONE, ESYS_TR_NONE,
3247 newAuthValue);
3248 return_if_error(r, "HierarchyChangeAuth");
3249 fallthrough;
3250
3251 statecase(context->hierarchy_state, HIERARCHY_CHANGE_AUTH_AUTH_SENT);
3252 r = Esys_HierarchyChangeAuth_Finish(context->esys);
3253 FAPI_SYNC(r, "Hierarchy change auth.", error);
3254
3255 context->hierarchy_state = HIERARCHY_CHANGE_AUTH_INIT;
3256 return r;
3257
3258 statecasedefault(context->hierarchy_state);
3259 }
3260
3261 error:
3262 return r;
3263 }
3264
3265 /** State machine for changing the policy of a hierarchy.
3266 *
3267 * Based on a passed policy the policy digest will be computed.
3268 * First it will be tried to set the policy of the hierarchy with a
3269 * "null" authorization. If this trial is not successful it will be tried to
3270 * authorize the hierarchy via a callback.
3271 * If an not null auth value is passed with_auth is set to yes for the
3272 * object otherwise to no. So for later authorizations it will be clear
3273 * whether null authorization is possible or not.
3274 *
3275 * @param[in] context The FAPI_CONTEXT.
3276 * @param[in] handle The ESAPI handle of the hierarchy.
3277 * @param[in,out] hierarchy_object The internal FAPI representation of a
3278 * hierarchy.
3279 * @param[in] policy The new policy assigned to the hierarchy.
3280 *
3281 * @retval TSS2_RC_SUCCESS on success.
3282 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
3283 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
3284 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
3285 * not covered by other return codes.
3286 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during policy calculation.
3287 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
3288 * store.
3289 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If an object needed for policy calculation was
3290 * not found.
3291 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
3292 * not successful.
3293 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
3294 * this function needs to be called again.
3295 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
3296 * operation already pending.
3297 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3298 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
3299 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
3300 * is not set.
3301 */
3302 TSS2_RC
3303 ifapi_change_policy_hierarchy(
3304 FAPI_CONTEXT *context,
3305 ESYS_TR handle,
3306 IFAPI_OBJECT *hierarchy_object,
3307 TPMS_POLICY *policy)
3308 {
3309 TSS2_RC r;
3310
3311 switch (context->hierarchy_policy_state) {
3312 statecase(context->hierarchy_policy_state, HIERARCHY_CHANGE_POLICY_INIT);
3313 if (! policy || ! policy->policy) {
3314 /* No policy will be used for hierarchy */
3315 return TSS2_RC_SUCCESS;
3316 }
3317
3318 context->policy.state = POLICY_INIT;
3319
3320 /* Calculate the policy digest which will be used as hierarchy policy. */
3321 r = ifapi_calculate_tree(context, NULL, /**< no path needed */
3322 policy,
3323 context->profiles.default_profile.nameAlg,
3324 &context->cmd.Provision.digest_idx,
3325 &context->cmd.Provision.hash_size);
3326 goto_if_error(r, "Policy calculation", error);
3327
3328
3329 /* Policy data will be stored in the provisioning context. */
3330 context->cmd.Provision.policy_digest.size = context->cmd.Provision.hash_size;
3331 memcpy(&context->cmd.Provision.policy_digest.buffer[0],
3332 &policy
3333 ->policyDigests.digests[context->cmd.Provision.digest_idx].digest,
3334 context->cmd.Provision.hash_size);
3335
3336 hierarchy_object->policy = policy;
3337 hierarchy_object->misc.hierarchy.authPolicy = context->cmd.Provision.policy_digest;
3338
3339 /* Prepare the setting of the policy. */
3340 r = Esys_SetPrimaryPolicy_Async(context->esys, handle,
3341 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
3342 &context->cmd.Provision.policy_digest,
3343 context->profiles.default_profile.nameAlg);
3344 return_if_error(r, "Esys_SetPrimaryPolicy_Async");
3345 fallthrough;
3346
3347 statecase(context->hierarchy_policy_state, HIERARCHY_CHANGE_POLICY_NULL_AUTH_SENT);
3348 r = Esys_SetPrimaryPolicy_Finish(context->esys);
3349 return_try_again(r);
3350 if ((r & ~TPM2_RC_N_MASK) != TPM2_RC_BAD_AUTH) {
3351 return_if_error(r, "SetPrimaryPolicy_Finish");
3352 context->hierarchy_policy_state = HIERARCHY_CHANGE_POLICY_INIT;
3353 return TSS2_RC_SUCCESS;
3354 }
3355
3356 /* Retry after NULL authorization was not successful */
3357 ifapi_init_hierarchy_object(hierarchy_object, handle);
3358 r = ifapi_set_auth(context, hierarchy_object, "Hierarchy object");
3359 return_if_error(r, "HierarchyChangePolicy");
3360
3361 r = Esys_SetPrimaryPolicy_Async(context->esys, handle,
3362 context->session1, ESYS_TR_NONE, ESYS_TR_NONE,
3363 &context->cmd.Provision.policy_digest,
3364 context->profiles.default_profile.nameAlg);
3365 return_if_error(r, "Esys_SetPrimaryPolicy_Async");
3366
3367 fallthrough;
3368
3369 statecase(context->hierarchy_policy_state, HIERARCHY_CHANGE_POLICY_AUTH_SENT);
3370 r = Esys_SetPrimaryPolicy_Finish(context->esys);
3371 return_try_again(r);
3372 return_if_error(r, "SetPrimaryPolicy_Finish");
3373
3374 return TSS2_RC_SUCCESS;
3375
3376 statecasedefault(context->hierarchy_policy_state);
3377 }
3378
3379 error:
3380 return r;
3381 }
3382
3383 /** Allocate ifapi object and store the result in a linked list.
3384 *
3385 * Allocated ifapi objects will be recorded in the context.
3386 *
3387 * @param[in,out] context The FAPI_CONTEXT.
3388 *
3389 * @retval The allocated ifapi object.
3390 * @retval NULL if the object cannot be allocated.
3391 */
3392 IFAPI_OBJECT
3393 *ifapi_allocate_object(FAPI_CONTEXT *context)
3394 {
3395 NODE_OBJECT_T *node = calloc(1, sizeof(NODE_OBJECT_T));
3396 if (!node)
3397 return NULL;
3398
3399 node->object = calloc(1, sizeof(IFAPI_OBJECT));
3400 if (!node->object) {
3401 free(node);
3402 return NULL;
3403 }
3404 node->next = context->object_list;
3405 context->object_list = node;
3406 return (IFAPI_OBJECT *) node->object;
3407 }
3408
3409 /** Free all ifapi objects stored in the context.
3410 *
3411 * @param[in,out] context The FAPI_CONTEXT.
3412 */
3413 void
3414 ifapi_free_objects(FAPI_CONTEXT *context)
3415 {
3416 NODE_OBJECT_T *free_node;
3417 NODE_OBJECT_T *node = context->object_list;
3418 while (node) {
3419 free(node->object);
3420 free_node = node;
3421 node = node->next;
3422 free(free_node);
3423 }
3424 }
3425
3426 /** Free ifapi a object stored in the context.
3427 *
3428 * @param[in,out] context The FAPI_CONTEXT.
3429 * @param[in,out] object The object which should be removed from the
3430 * the linked list stored in context.
3431 */
3432 void
3433 ifapi_free_object(FAPI_CONTEXT *context, IFAPI_OBJECT **object)
3434 {
3435 NODE_OBJECT_T *node;
3436 NODE_OBJECT_T **update_ptr;
3437
3438 for (node = context->object_list,
3439 update_ptr = &context->object_list;
3440 node != NULL;
3441 update_ptr = &node->next, node = node->next) {
3442 if (node->object == object) {
3443 *update_ptr = node->next;
3444 SAFE_FREE(node->object);
3445 SAFE_FREE(node);
3446 *object = NULL;
3447 return;
3448 }
3449 }
3450 }
3451
3452 #define ADD_CAPABILITY_INFO(capability, field, subfield, max_count, property_count) \
3453 if (context->cmd.GetInfo.fetched_data->data.capability.count > max_count - property_count) { \
3454 context->cmd.GetInfo.fetched_data->data.capability.count = max_count - property_count; \
3455 } \
3456 \
3457 memmove(&context->cmd.GetInfo.capability_data->data.capability.field[property_count], \
3458 context->cmd.GetInfo.fetched_data->data.capability.field, \
3459 context->cmd.GetInfo.fetched_data->data.capability.count \
3460 * sizeof(context->cmd.GetInfo.fetched_data->data.capability.field[0])); \
3461 property_count += context->cmd.GetInfo.fetched_data->data.capability.count; \
3462 \
3463 context->cmd.GetInfo.capability_data->data.capability.count = property_count; \
3464 \
3465 if (more_data && property_count < count \
3466 && context->cmd.GetInfo.fetched_data->data.capability.count) { \
3467 context->cmd.GetInfo.property \
3468 = context->cmd.GetInfo.capability_data->data. \
3469 capability.field[property_count - 1]subfield + 1; \
3470 } else { \
3471 more_data = false; \
3472 }
3473
3474
3475 /** Prepare the receiving of capability data.
3476 *
3477 * @param[in,out] context The FAPI_CONTEXT.
3478 *
3479 * @retval TSS2_RC_SUCCESS.
3480 */
3481 TPM2_RC
3482 ifapi_capability_init(FAPI_CONTEXT *context)
3483 {
3484 context->cmd.GetInfo.capability_data = NULL;
3485 context->cmd.GetInfo.fetched_data = NULL;
3486
3487 return TSS2_RC_SUCCESS;
3488
3489
3490 }
3491
3492 /** State machine for receiving TPM capability information.
3493 *
3494 * The state machine shares the state with the FAPI function Fapi_GetInfo.
3495 * context->state == GET_INFO_GET_CAP_MORE signals that more capability data can
3496 * be retrieved.
3497 *
3498 * @param[in,out] context The FAPI_CONTEXT.
3499 * @param[in] capability The capability to be retrieved.
3500 * @param[in] count The maximal number of items that should be retrieved.
3501 * @param[out] capability_data The retrieved capability information.
3502 *
3503 * @retval TSS2_RC_SUCCESS If all capability data is retrieved.
3504 * @retval TSS2_FAPI_RC_TRY_AGAIN if more capability data is available.
3505 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
3506 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
3507 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
3508 * the function.
3509 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
3510 * operation already pending.
3511 */
3512 TPM2_RC
3513 ifapi_capability_get(FAPI_CONTEXT *context, TPM2_CAP capability,
3514 UINT32 count, TPMS_CAPABILITY_DATA **capability_data) {
3515
3516 TPMI_YES_NO more_data;
3517 TSS2_RC r = TSS2_RC_SUCCESS;
3518 ESYS_CONTEXT *ectx = context->esys;
3519
3520 switch (context->state) {
3521 statecase(context->state, GET_INFO_GET_CAP);
3522 /* fetch capability info */
3523 context->cmd.GetInfo.fetched_data = NULL;
3524 context->cmd.GetInfo.capability_data = NULL;
3525 fallthrough;
3526
3527 statecase(context->state, GET_INFO_GET_CAP_MORE);
3528 r = Esys_GetCapability_Async(ectx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
3529 capability, context->cmd.GetInfo.property,
3530 count - context->cmd.GetInfo.property_count);
3531 goto_if_error(r, "Error GetCapability", error_cleanup);
3532 fallthrough;
3533
3534 statecase(context->state, GET_INFO_WAIT_FOR_CAP);
3535 r = Esys_GetCapability_Finish(ectx, &more_data, &context->cmd.GetInfo.fetched_data);
3536 return_try_again(r);
3537 goto_if_error(r, "Error GetCapability", error_cleanup);
3538
3539 LOG_TRACE("GetCapability: capability: 0x%x, property: 0x%x", capability,
3540 context->cmd.GetInfo.property);
3541
3542 if (context->cmd.GetInfo.fetched_data->capability != capability) {
3543 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
3544 "TPM returned different capability than requested: 0x%x != 0x%x",
3545 error_cleanup,
3546 context->cmd.GetInfo.fetched_data->capability, capability);
3547 }
3548
3549 if (context->cmd.GetInfo.capability_data == NULL) {
3550 /* reuse the TPM's result structure */
3551 context->cmd.GetInfo.capability_data = context->cmd.GetInfo.fetched_data;
3552
3553 if (!more_data) {
3554 /* there won't be another iteration of the loop, just return the result unmodified */
3555 *capability_data = context->cmd.GetInfo.capability_data;
3556 return TPM2_RC_SUCCESS;
3557 }
3558 }
3559
3560 /* append the TPM's results to the initial structure, as long as there is still space left */
3561 switch (capability) {
3562 case TPM2_CAP_ALGS:
3563 ADD_CAPABILITY_INFO(algorithms, algProperties, .alg,
3564 TPM2_MAX_CAP_ALGS,
3565 context->cmd.GetInfo.property_count);
3566 break;
3567 case TPM2_CAP_HANDLES:
3568 ADD_CAPABILITY_INFO(handles, handle,,
3569 TPM2_MAX_CAP_HANDLES,
3570 context->cmd.GetInfo.property_count);
3571 break;
3572 case TPM2_CAP_COMMANDS:
3573 ADD_CAPABILITY_INFO(command, commandAttributes,,
3574 TPM2_MAX_CAP_CC,
3575 context->cmd.GetInfo.property_count);
3576 /* workaround because tpm2-tss does not implement attribute commandIndex for TPMA_CC */
3577 context->cmd.GetInfo.property &= TPMA_CC_COMMANDINDEX_MASK;
3578 break;
3579 case TPM2_CAP_PP_COMMANDS:
3580 ADD_CAPABILITY_INFO(ppCommands, commandCodes,,
3581 TPM2_MAX_CAP_CC,
3582 context->cmd.GetInfo.property_count);
3583 break;
3584 case TPM2_CAP_AUDIT_COMMANDS:
3585 ADD_CAPABILITY_INFO(auditCommands, commandCodes,,
3586 TPM2_MAX_CAP_CC,
3587 context->cmd.GetInfo.property_count);
3588 break;
3589 case TPM2_CAP_PCRS:
3590 ADD_CAPABILITY_INFO(assignedPCR, pcrSelections, .hash,
3591 TPM2_NUM_PCR_BANKS,
3592 context->cmd.GetInfo.property_count);
3593 break;
3594 case TPM2_CAP_TPM_PROPERTIES:
3595 ADD_CAPABILITY_INFO(tpmProperties, tpmProperty, .property,
3596 TPM2_MAX_TPM_PROPERTIES,
3597 context->cmd.GetInfo.property_count);
3598 break;
3599 case TPM2_CAP_PCR_PROPERTIES:
3600 ADD_CAPABILITY_INFO(pcrProperties, pcrProperty, .tag,
3601 TPM2_MAX_PCR_PROPERTIES,
3602 context->cmd.GetInfo.property_count);
3603 break;
3604 case TPM2_CAP_ECC_CURVES:
3605 ADD_CAPABILITY_INFO(eccCurves, eccCurves,,
3606 TPM2_MAX_ECC_CURVES,
3607 context->cmd.GetInfo.property_count);
3608 break;
3609 case TPM2_CAP_VENDOR_PROPERTY:
3610 ADD_CAPABILITY_INFO(intelPttProperty, property,,
3611 TPM2_MAX_PTT_PROPERTIES,
3612 context->cmd.GetInfo.property_count);
3613 break;
3614 default:
3615 LOG_ERROR("Unsupported capability: 0x%x\n", capability);
3616 if (context->cmd.GetInfo.fetched_data != context->cmd.GetInfo.capability_data) {
3617 free(context->cmd.GetInfo.fetched_data);
3618 }
3619 free(context->cmd.GetInfo.capability_data);
3620 *capability_data = NULL;
3621 return TSS2_FAPI_RC_BAD_VALUE;
3622 }
3623
3624 if (context->cmd.GetInfo.fetched_data != context->cmd.GetInfo.capability_data) {
3625 free(context->cmd.GetInfo.fetched_data);
3626 }
3627 *capability_data = context->cmd.GetInfo.capability_data;
3628 break;
3629
3630 statecasedefault(context->state);
3631 }
3632 if (more_data) {
3633 context->state = GET_INFO_GET_CAP_MORE;
3634 return TSS2_FAPI_RC_TRY_AGAIN;
3635 } else {
3636 context->state = _FAPI_STATE_INIT;
3637 return TSS2_RC_SUCCESS;
3638 }
3639
3640 error_cleanup:
3641 context->state = _FAPI_STATE_INIT;
3642 SAFE_FREE(context->cmd.GetInfo.capability_data);
3643 SAFE_FREE(context->cmd.GetInfo.fetched_data);
3644 return r;
3645 }
3646
3647 /** Get certificates stored in NV ram.
3648 *
3649 * The NV handles in the certificate range are determined. The corresponding
3650 * certificates are read out and stored in a linked list.
3651 *
3652 * @param[in,out] context The FAPI_CONTEXT. The sub context for NV reading
3653 * will be used.
3654 * @param[in] min_handle The first possible handle in the handle range.
3655 * @param[in] max_handle Maximal handle to filter out the handles not in the
3656 * handle range for certificates.
3657 * @param[out] cert_list The callee allocates linked list of certificates.
3658 *
3659 * @retval TSS2_RC_SUCCESS on success.
3660 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
3661 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
3662 *
3663 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
3664 * this function needs to be called again.
3665 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
3666 * operation already pending.
3667 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
3668 * is not set.
3669 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
3670 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
3671 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
3672 * object store.
3673 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
3674 * was not successful.
3675 */
3676 TSS2_RC
3677 ifapi_get_certificates(
3678 FAPI_CONTEXT *context,
3679 UINT32 min_handle,
3680 UINT32 max_handle,
3681 NODE_OBJECT_T **cert_list)
3682 {
3683 TSS2_RC r;
3684 TPMI_YES_NO moreData;
3685 TPMS_CAPABILITY_DATA **capabilityData = &context->cmd.Provision.capabilityData;
3686 TPM2B_NV_PUBLIC *nvPublic;
3687 uint8_t *cert_data;
3688 size_t cert_size;
3689
3690 context->cmd.Provision.cert_nv_idx = MIN_EK_CERT_HANDLE;
3691 context->cmd.Provision.capabilityData = NULL;
3692
3693 switch (context->get_cert_state) {
3694 statecase(context->get_cert_state, GET_CERT_INIT);
3695 *cert_list = NULL;
3696 context->cmd.Provision.cert_idx = 0;
3697 /* Prepare the reading of the capability handles in the certificate range */
3698 r = Esys_GetCapability_Async(context->esys,
3699 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
3700 TPM2_CAP_HANDLES, min_handle,
3701 TPM2_MAX_CAP_HANDLES);
3702 goto_if_error(r, "Esys_GetCapability_Async", error);
3703 fallthrough;
3704
3705 statecase(context->get_cert_state, GET_CERT_WAIT_FOR_GET_CAP);
3706 r = Esys_GetCapability_Finish(context->esys, &moreData, capabilityData);
3707 return_try_again(r);
3708 goto_if_error_reset_state(r, "GetCapablity_Finish", error);
3709
3710 if (!*capabilityData || (*capabilityData)->data.handles.count == 0) {
3711 *cert_list = NULL;
3712 return TSS2_RC_SUCCESS;
3713 }
3714 context->cmd.Provision.capabilityData = *capabilityData;
3715 context->cmd.Provision.cert_count = (*capabilityData)->data.handles.count;
3716
3717 /* Filter out NV handles beyond the EK cert range */
3718 for (size_t i = 0; i < context->cmd.Provision.cert_count; i++) {
3719 if (context->cmd.Provision.capabilityData->data.handles.handle[i] > max_handle) {
3720 context->cmd.Provision.cert_count = i;
3721 break;
3722 }
3723 }
3724 fallthrough;
3725
3726 statecase(context->get_cert_state, GET_CERT_GET_CERT_NV);
3727 goto_if_null(context->cmd.Provision.capabilityData,
3728 "capabilityData is null", TSS2_FAPI_RC_MEMORY, error);
3729 context->cmd.Provision.cert_nv_idx
3730 = context->cmd.Provision.capabilityData
3731 ->data.handles.handle[context->cmd.Provision.cert_idx];
3732
3733 ifapi_init_hierarchy_object(&context->nv_cmd.auth_object,
3734 TPM2_RH_OWNER);
3735
3736 r = Esys_TR_FromTPMPublic_Async(context->esys,
3737 context->cmd.Provision.cert_nv_idx,
3738 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE);
3739 goto_if_error_reset_state(r, "Esys_TR_FromTPMPublic_Async", error);
3740 fallthrough;
3741
3742 statecase(context->get_cert_state, GET_CERT_GET_CERT_NV_FINISH);
3743 r = Esys_TR_FromTPMPublic_Finish(context->esys,
3744 &context->cmd.Provision.esys_nv_cert_handle);
3745 return_try_again(r);
3746 goto_if_error_reset_state(r, "TR_FromTPMPublic_Finish", error);
3747
3748 /* Read public to get size of certificate */
3749 r = Esys_NV_ReadPublic_Async(context->esys,
3750 context->cmd.Provision.esys_nv_cert_handle,
3751 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE);
3752 goto_if_error_reset_state(r, "Esys_NV_ReadPublic_Async", error);
3753 fallthrough;
3754
3755 statecase(context->get_cert_state, GET_CERT_GET_CERT_READ_PUBLIC);
3756 r = Esys_NV_ReadPublic_Finish(context->esys,
3757 &nvPublic,
3758 NULL);
3759 return_try_again(r);
3760 goto_if_error(r, "Error: nv read public", error);
3761
3762 /* TPMA_NV_NO_DA is set for NV certificate */
3763 context->nv_cmd.nv_object.misc.nv.public.nvPublic.attributes = TPMA_NV_NO_DA;
3764
3765 /* Prepare context for nv read */
3766 context->nv_cmd.data_idx = 0;
3767 context->nv_cmd.auth_index = ESYS_TR_RH_OWNER;
3768 context->nv_cmd.numBytes = nvPublic->nvPublic.dataSize;
3769 context->nv_cmd.esys_handle = context->cmd.Provision.esys_nv_cert_handle;
3770 context->nv_cmd.offset = 0;
3771 context->cmd.Provision.pem_cert = NULL;
3772 context->session1 = ESYS_TR_PASSWORD;
3773 context->session2 = ESYS_TR_NONE;
3774 context->nv_cmd.nv_read_state = NV_READ_INIT;
3775 memset(&context->nv_cmd.nv_object, 0, sizeof(IFAPI_OBJECT));
3776 Esys_Free(nvPublic);
3777 fallthrough;
3778
3779 statecase(context->get_cert_state, GET_CERT_READ_CERT);
3780 r = ifapi_nv_read(context, &cert_data, &cert_size);
3781 return_try_again(r);
3782 goto_if_error_reset_state(r, " FAPI NV_Read", error);
3783
3784 context->cmd.Provision.cert_idx += 1;
3785
3786 /* Add cert to list */
3787 if (context->cmd.Provision.cert_idx == context->cmd.Provision.cert_count) {
3788 context->get_cert_state = GET_CERT_GET_CERT_NV;
3789
3790 r = push_object_with_size_to_list(cert_data, cert_size, cert_list);
3791 goto_if_error(r, "Store certificate in list.", error);
3792
3793 return TSS2_RC_SUCCESS;
3794 } else {
3795 context->get_cert_state = GET_CERT_GET_CERT_NV;
3796 }
3797 break;
3798
3799 statecasedefault(context->get_cert_state);
3800 }
3801
3802 error:
3803 ifapi_free_object_list(*cert_list);
3804 return r;
3805 }
3806
3807
3808 /** Get description of an internal FAPI object.
3809 *
3810 * @param[in] object The object with the description.
3811 * @param[out] description The callee allocated description.
3812 *
3813 * @retval TSS2_RC_SUCCESS If a copy of the description can be returned
3814 * or if no description exists.
3815 * @retval TSS2_FAPI_RC_MEMORY in the copy cannot be allocated.
3816 */
3817 TSS2_RC
3818 ifapi_get_description(IFAPI_OBJECT *object, char **description)
3819 {
3820 char *obj_description = NULL;
3821
3822 switch (object->objectType) {
3823 case IFAPI_KEY_OBJ:
3824 obj_description = object->misc.key.description;
3825 break;
3826 case IFAPI_NV_OBJ:
3827 obj_description = object->misc.nv.description;
3828 break;
3829 case IFAPI_HIERARCHY_OBJ:
3830 obj_description = object->misc.hierarchy.description;
3831 break;
3832 default:
3833 *description = NULL;
3834 return TSS2_RC_SUCCESS;
3835 }
3836 if (obj_description) {
3837 *description = strdup(obj_description);
3838 check_oom(*description);
3839 } else {
3840 *description = NULL;
3841 }
3842 return TSS2_RC_SUCCESS;
3843 }
3844
3845 /** Set description of an internal FAPI object.
3846 *
3847 * @param[in,out] object The object with the description.
3848 * @param[in] description The description char strint or NULL.
3849 */
3850 void
3851 ifapi_set_description(IFAPI_OBJECT *object, char *description)
3852 {
3853 switch (object->objectType) {
3854 case IFAPI_KEY_OBJ:
3855 SAFE_FREE(object->misc.key.description);
3856 object->misc.key.description = description;
3857 break;
3858 case IFAPI_NV_OBJ:
3859 SAFE_FREE(object->misc.nv.description);
3860 object->misc.nv.description = description;
3861 break;
3862 case IFAPI_HIERARCHY_OBJ:
3863 SAFE_FREE(object->misc.hierarchy.description);
3864 object->misc.hierarchy.description = description;
3865 break;
3866 default:
3867 LOG_WARNING("Description can't be set");
3868 break;
3869 }
3870 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef FAPI_UTIL_H
6 #define FAPI_UTIL_H
7
8 #include <stdint.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <json-c/json.h>
13 #include <json-c/json_util.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "ifapi_helpers.h"
19
20
21 TSS2_RC
22 ifapi_flush_object(FAPI_CONTEXT *context, ESYS_TR session);
23
24 TSS2_RC
25 ifapi_get_session_async(
26 ESYS_CONTEXT *esys,
27 ESYS_TR saltkey,
28 const IFAPI_PROFILE*profile,
29 TPMI_ALG_HASH hashAlg);
30
31 TSS2_RC
32 ifapi_get_session_finish(ESYS_CONTEXT *esys, ESYS_TR *session,
33 TPMA_SESSION flags);
34
35 TSS2_RC
36 ifapi_set_auth(
37 FAPI_CONTEXT *context,
38 IFAPI_OBJECT *auth_object,
39 const char *description);
40
41 TSS2_RC
42 ifapi_get_free_handle_async(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle);
43
44 TSS2_RC
45 ifapi_get_free_handle_finish(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle,
46 TPM2_HANDLE max);
47
48 TSS2_RC
49 ifapi_init_primary_async(
50 FAPI_CONTEXT *context,
51 TSS2_KEY_TYPE ktype);
52
53 TSS2_RC
54 ifapi_init_primary_finish(
55 FAPI_CONTEXT *context,
56 TSS2_KEY_TYPE ktype);
57
58 TSS2_RC
59 ifapi_session_init(FAPI_CONTEXT *context);
60
61 TSS2_RC
62 ifapi_non_tpm_mode_init(FAPI_CONTEXT *context);
63
64 void
65 ifapi_session_clean(FAPI_CONTEXT *context);
66
67 TSS2_RC
68 ifapi_cleanup_session(FAPI_CONTEXT *context);
69
70 void
71 ifapi_primary_clean(FAPI_CONTEXT *context);
72
73 TSS2_RC
74 ifapi_get_sessions_async(
75 FAPI_CONTEXT *context,
76 IFAPI_SESSION_TYPE session_flags,
77 TPMA_SESSION attribute_flags1,
78 TPMA_SESSION attribute_flags2);
79
80 TSS2_RC
81 ifapi_get_sessions_finish(
82 FAPI_CONTEXT *context,
83 const IFAPI_PROFILE *profile,
84 TPMI_ALG_HASH hash_alg);
85
86 TSS2_RC
87 ifapi_merge_profile_into_nv_template(
88 FAPI_CONTEXT *context,
89 IFAPI_NV_TEMPLATE *template);
90
91 TSS2_RC
92 ifapi_merge_profile_into_template(
93 const IFAPI_PROFILE *profile,
94 IFAPI_KEY_TEMPLATE *template);
95
96 TSS2_RC
97 ifapi_load_key_async(FAPI_CONTEXT *context, size_t position);
98
99 TSS2_RC
100 ifapi_load_key_finish(FAPI_CONTEXT *context, bool flush_parent);
101
102 TSS2_RC
103 ifapi_load_keys_async(
104 FAPI_CONTEXT *context,
105 char const *keyPath);
106
107 TSS2_RC
108 ifapi_load_keys_finish(
109 FAPI_CONTEXT *context,
110 bool flush_parent,
111 ESYS_TR *handle,
112 IFAPI_OBJECT **key_object);
113
114 TSS2_RC
115 ifapi_nv_read(
116 FAPI_CONTEXT *context,
117 uint8_t **data,
118 size_t *size);
119
120 void
121 ifapi_flush_policy_session(
122 FAPI_CONTEXT *context,
123 ESYS_TR session,
124 TSS2_RC r);
125
126 TSS2_RC
127 ifapi_nv_write(
128 FAPI_CONTEXT *context,
129 char *nvPath,
130 size_t param_offset,
131 uint8_t const *data,
132 size_t size);
133
134 TSS2_RC
135 ifapi_get_random(
136 FAPI_CONTEXT *context,
137 size_t numBytes,
138 uint8_t **data);
139
140 TSS2_RC
141 ifapi_load_key(
142 FAPI_CONTEXT *context,
143 char const *keyPath,
144 IFAPI_OBJECT **key_object);
145
146 TSS2_RC
147 ifapi_key_sign(
148 FAPI_CONTEXT *context,
149 IFAPI_OBJECT *sig_key_object,
150 char const *padding,
151 TPM2B_DIGEST *digest,
152 TPMT_SIGNATURE **tpm_signature,
153 char **publicKey,
154 char **certificate);
155
156 TSS2_RC
157 ifapi_authorize_object(
158 FAPI_CONTEXT *context,
159 IFAPI_OBJECT *object,
160 ESYS_TR *session);
161
162 TSS2_RC
163 ifapi_get_json(
164 FAPI_CONTEXT *context,
165 IFAPI_OBJECT *object,
166 char **json_string);
167
168 TSS2_RC
169 ifapi_key_create_prepare(
170 FAPI_CONTEXT *context,
171 char const *keyPath,
172 char const *policyPath);
173
174 TSS2_RC
175 ifapi_key_create_prepare_auth(
176 FAPI_CONTEXT *context,
177 char const *keyPath,
178 char const *policyPath,
179 char const *authValue);
180
181 TSS2_RC
182 ifapi_key_create_prepare_sensitive(
183 FAPI_CONTEXT *context,
184 char const *keyPath,
185 char const *policyPath,
186 size_t dataSize,
187 char const *authValue,
188 uint8_t const *data);
189
190 TSS2_RC
191 ifapi_key_create(
192 FAPI_CONTEXT *context,
193 IFAPI_KEY_TEMPLATE *template);
194
195 TSS2_RC
196 ifapi_get_sig_scheme(
197 FAPI_CONTEXT *context,
198 IFAPI_OBJECT *object,
199 char const *padding,
200 TPM2B_DIGEST *digest,
201 TPMT_SIG_SCHEME *sig_scheme);
202
203 TSS2_RC
204 ifapi_change_auth_hierarchy(
205 FAPI_CONTEXT *context,
206 ESYS_TR handle,
207 IFAPI_OBJECT *hierarchy_object,
208 TPM2B_AUTH *newAuthValue);
209
210 TSS2_RC
211 ifapi_change_policy_hierarchy(
212 FAPI_CONTEXT *context,
213 ESYS_TR handle,
214 IFAPI_OBJECT *hierarchy_object,
215 TPMS_POLICY *policy);
216
217 IFAPI_OBJECT
218 *ifapi_allocate_object(FAPI_CONTEXT *context);
219
220 void
221 ifapi_free_objects(FAPI_CONTEXT *context);
222
223 void
224 ifapi_free_object(FAPI_CONTEXT *context, IFAPI_OBJECT **object);
225
226 TPM2_RC
227 ifapi_capability_init(FAPI_CONTEXT *context);
228
229 TPM2_RC
230 ifapi_capability_get(FAPI_CONTEXT *context, TPM2_CAP capability,
231 UINT32 count, TPMS_CAPABILITY_DATA **capability_data);
232
233 TSS2_RC
234 ifapi_get_certificates(
235 FAPI_CONTEXT *context,
236 UINT32 min_handle,
237 UINT32 max_handle,
238 NODE_OBJECT_T **cert_list);
239
240 TSS2_RC
241 ifapi_initialize_object(
242 ESYS_CONTEXT *ectx,
243 IFAPI_OBJECT *object);
244
245 TSS2_RC
246 ifapi_esys_serialize_object(
247 ESYS_CONTEXT *ectx,
248 IFAPI_OBJECT *object);
249
250 TSS2_RC
251 ifapi_get_description(IFAPI_OBJECT *object, char **description);
252
253 void
254 ifapi_set_description(IFAPI_OBJECT *object, char *description);
255
256 #endif /* FAPI_UTIL_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <json-c/json.h>
11 #include <json-c/json_util.h>
12
13 #include "util/aux_util.h"
14 #include "ifapi_config.h"
15 #include "ifapi_json_deserialize.h"
16 #include "tpm_json_deserialize.h"
17 #include "ifapi_helpers.h"
18
19 #define LOGMODULE fapi
20 #include "util/log.h"
21
22 /**
23 * The path of the default config file
24 */
25 #define DEFAULT_CONFIG_FILE (SYSCONFDIR "/tpm2-tss/fapi-config.json")
26
27 /** Deserializes a configuration JSON object.
28 *
29 * @param[in] jso The JSON object to be deserialized
30 * @param[out] out The deserialized configuration object
31 *
32 * @retval TSS2_RC_SUCCESS on success
33 * @retval TSS2_FAPI_RC_BAD_REFERENCE if jso or out is NULL
34 * @retval TSS2_FAPI_RC_BAD_VALUE if the JSON object cannot be deserialized
35 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
36 */
37 static TSS2_RC
38 ifapi_json_IFAPI_CONFIG_deserialize(json_object *jso, IFAPI_CONFIG *out)
39 {
40 /* Check for NULL parameters */
41 return_if_null(out, "out is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
42 return_if_null(jso, "jso is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
43
44 /* Deserialize the JSON object) */
45 json_object *jso2;
46 TSS2_RC r;
47 LOG_TRACE("call");
48
49 if (!ifapi_get_sub_object(jso, "profile_dir", &jso2)) {
50 out->profile_dir = NULL;
51 } else {
52 r = ifapi_json_char_deserialize(jso2, &out->profile_dir);
53 return_if_error(r, "BAD VALUE");
54 }
55
56 if (!ifapi_get_sub_object(jso, "user_dir", &jso2)) {
57 out->user_dir = NULL;
58 } else {
59 r = ifapi_json_char_deserialize(jso2, &out->user_dir);
60 return_if_error(r, "BAD VALUE");
61 }
62
63 if (!ifapi_get_sub_object(jso, "system_dir", &jso2)) {
64 out->keystore_dir = NULL;
65 } else {
66 r = ifapi_json_char_deserialize(jso2, &out->keystore_dir);
67 return_if_error(r, "BAD VALUE");
68 }
69
70 if (!ifapi_get_sub_object(jso, "log_dir", &jso2)) {
71 out->log_dir = DEFAULT_LOG_DIR;
72 } else {
73 r = ifapi_json_char_deserialize(jso2, &out->log_dir);
74 return_if_error(r, "BAD VALUE");
75 }
76
77 if (!ifapi_get_sub_object(jso, "profile_name", &jso2)) {
78 LOG_ERROR("Bad value");
79 return TSS2_FAPI_RC_BAD_VALUE;
80 }
81 r = ifapi_json_char_deserialize(jso2, &out->profile_name);
82 return_if_error(r, "BAD VALUE");
83 if (!ifapi_get_sub_object(jso, "tcti", &jso2)) {
84 LOG_ERROR("Bad value");
85 return TSS2_FAPI_RC_BAD_VALUE;
86 }
87 r = ifapi_json_char_deserialize(jso2, &out->tcti);
88 return_if_error(r, "BAD VALUE");
89
90 if (!ifapi_get_sub_object(jso, "system_pcrs", &jso2)) {
91 LOG_ERROR("Bad value");
92 return TSS2_FAPI_RC_BAD_VALUE;
93 }
94 r = ifapi_json_TPML_PCR_SELECTION_deserialize(jso2, &out->system_pcrs);
95 return_if_error(r, "BAD VALUE");
96
97 if (!ifapi_get_sub_object(jso, "ek_cert_file", &jso2)) {
98 out->ek_cert_file = NULL;
99 } else {
100 r = ifapi_json_char_deserialize(jso2, &out->ek_cert_file);
101 return_if_error(r, "BAD VALUE");
102 }
103
104 if (ifapi_get_sub_object(jso, "ek_cert_less", &jso2)) {
105 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->ek_cert_less);
106 return_if_error(r, "BAD VALUE");
107
108 } else {
109 out->ek_cert_less = TPM2_NO;
110 }
111
112 if (ifapi_get_sub_object(jso, "ek_fingerprint", &jso2)) {
113 r = ifapi_json_TPMT_HA_deserialize(jso2, &out->ek_fingerprint);
114 return_if_error(r, "BAD VALUE");
115 } else {
116 out->ek_fingerprint.hashAlg = 0;
117 }
118
119 if (!ifapi_get_sub_object(jso, "intel_cert_service", &jso2)) {
120 out->intel_cert_service = NULL;
121 } else {
122 r = ifapi_json_char_deserialize(jso2, &out->intel_cert_service);
123 return_if_error(r, "BAD VALUE");
124 }
125
126 LOG_TRACE("true");
127 return TSS2_RC_SUCCESS;
128 }
129
130 /**
131 * Starts the initialization of the FAPI configuration.
132 *
133 * @param[in] io An IO object for file system access
134 *
135 * @retval TSS2_RC_SUCCESS on success
136 * @retval TSS2_FAPI_RC_BAD_REFERENCE if io is NULL
137 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
138 * object store.
139 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
140 */
141 TSS2_RC
142 ifapi_config_initialize_async(IFAPI_IO *io)
143 {
144 /* Check for NULL parameters */
145 return_if_null(io, "io is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
146
147 /* Determine the location of the configuration file */
148 char *configFile = getenv(ENV_FAPI_CONFIG);
149 if (!configFile) {
150 /* No config file given, falling back to the default */
151 configFile = DEFAULT_CONFIG_FILE;
152 }
153
154 /* Start reading the config file */
155 TSS2_RC r = ifapi_io_read_async(io, configFile);
156 return_if_error(r, "Could not read config file ");
157 return TSS2_RC_SUCCESS;
158 }
159
160 /**
161 * Finishes the initialization of the FAPI configuration.
162 * @param[in] io An IO object for file system access
163 * @param[out] config The configuration that is initialized
164 *
165 * @retval TSS2_RC_SUCCESS on success
166 * @retval TSS2_FAPI_RC_BAD_REFERENCE if config or io is NULL
167 * @retval TSS2_FAPI_RC_BAD_VALUE if the read configuration file does not hold
168 * a valid configuration
169 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if JSON parsing fails
170 * @retval TSS2_FAPI_RC_BAD_PATH if the configuration path is invalid
171 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
172 * this function needs to be called again.
173 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
174 * object store.
175 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
176 */
177 TSS2_RC
178 ifapi_config_initialize_finish(IFAPI_IO *io, IFAPI_CONFIG *config)
179 {
180 /* Check for NULL parameters */
181 return_if_null(config, "config is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
182 return_if_null(io, "io is NULL", TSS2_FAPI_RC_BAD_REFERENCE);
183
184 /* Definitions that must be listed here for the cleanup to work */
185 char *homeDir = NULL;
186 json_object *jso = NULL;
187
188 /* Finish reading operation */
189 uint8_t *configFileContent = NULL;
190 size_t configFileContentSize = 0;
191 TSS2_RC r = ifapi_io_read_finish(io, &configFileContent, &configFileContentSize);
192 return_try_again(r);
193 goto_if_error(r, "Could not finish read operation", cleanup);
194 if (configFileContent == NULL || configFileContentSize == 0) {
195 LOG_ERROR("Config file is empty");
196 r = TSS2_FAPI_RC_BAD_VALUE;
197 goto cleanup;
198 }
199
200 /* Parse and deserialize the configuration file */
201 jso = json_tokener_parse((char *)configFileContent);
202 goto_if_null(jso, "Could not parse JSON objects",
203 TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
204 r = ifapi_json_IFAPI_CONFIG_deserialize(jso, config);
205 goto_if_error(r, "Could not deserialize configuration", cleanup);
206
207 /* Check, if the values of the configuration are valid */
208 goto_if_null(config->profile_dir, "No profile directory defined in config file",
209 TSS2_FAPI_RC_BAD_VALUE, cleanup);
210 goto_if_null(config->user_dir, "No user directory defined in config file",
211 TSS2_FAPI_RC_BAD_VALUE, cleanup);
212 goto_if_null(config->profile_name, "No default profile defined in config file.",
213 TSS2_FAPI_RC_BAD_VALUE, cleanup);
214
215 /* Check whether usage of home directory is provided in config file */
216 size_t startPos = 0;
217 if (strncmp("~", config->user_dir, 1) == 0) {
218 startPos = 1;
219 } else if (strncmp("$HOME", config->user_dir, 5) == 0) {
220 startPos = 5;
221 }
222
223 /* Replace home abbreviation in user path. */
224 char *homePath = NULL;
225 if (startPos != 0) {
226 LOG_DEBUG("Expanding user directory %s to user's home", config->user_dir);
227 homeDir = getenv("HOME");
228 goto_if_null2(homeDir, "Home directory can't be determined.",
229 r, TSS2_FAPI_RC_BAD_PATH, cleanup);
230
231 r = ifapi_asprintf(&homePath, "%s%s%s", homeDir, IFAPI_FILE_DELIM,
232 &config->user_dir[startPos]);
233 goto_if_error(r, "Out of memory.", cleanup);
234
235 SAFE_FREE(config->user_dir);
236 config->user_dir = homePath;
237 }
238
239 /* Log the contents of the configuration */
240 LOG_DEBUG("Configuration profile directory: %s", config->profile_dir);
241 LOG_DEBUG("Configuration user directory: %s", config->user_dir);
242 LOG_DEBUG("Configuration key storage directory: %s", config->keystore_dir);
243 LOG_DEBUG("Configuration profile name: %s", config->profile_name);
244 LOG_DEBUG("Configuration TCTI: %s", config->tcti);
245 LOG_DEBUG("Configuration log directory: %s", config->log_dir);
246 cleanup:
247 SAFE_FREE(configFileContent);
248 if (jso != NULL) {
249 json_object_put(jso);
250 }
251 return r;
252 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef IFAPI_CONFIG_H
6 #define IFAPI_CONFIG_H
7
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "tss2_tpm2_types.h"
12 #include "ifapi_io.h"
13
14 #define ENV_FAPI_CONFIG "TSS2_FAPICONF"
15
16 /**
17 * Type for storing FAPI configuration
18 */
19 typedef struct {
20 /** Path for profile directory */
21 char *profile_dir;
22 /** Directory storing NV objects */
23 char *user_dir;
24 /** Directory storing key and NV objects */
25 char *keystore_dir;
26 /** Name the used profile */
27 char *profile_name;
28 /** The used tcti interface */
29 char *tcti;
30 /** The directory for event logs */
31 char *log_dir;
32 /** The PCRs used by IMA etc. */
33 TPML_PCR_SELECTION system_pcrs;
34 /** Fingerprint of EK */
35 TPMT_HA ek_fingerprint;
36 /* URL for EC certificate */
37 char *ek_cert_file;
38 /* Switch whether certificate validation will done */
39 TPMI_YES_NO ek_cert_less;
40 /** Certificate service for Intel TPMs */
41 char *intel_cert_service;
42
43 } IFAPI_CONFIG;
44
45 TSS2_RC
46 ifapi_config_initialize_async(
47 IFAPI_IO *io
48 );
49
50 TSS2_RC
51 ifapi_config_initialize_finish(
52 IFAPI_IO *io,
53 IFAPI_CONFIG *config
54 );
55
56 #endif /* IFAPI_CONFIG_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11
12 #include "ifapi_helpers.h"
13 #include "ifapi_eventlog.h"
14 #include "ifapi_json_serialize.h"
15
16 #define LOGMODULE fapi
17 #include "util/log.h"
18 #include "util/aux_util.h"
19 #include "ifapi_macros.h"
20
21 /** Initialize the eventlog module of FAPI.
22 *
23 * @param[in,out] eventlog The context area for the eventlog.
24 * @param[in] log_dir The directory where to put the eventlog data.
25 * @retval TSS2_RC_SUCCESS on success.
26 * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
27 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
28 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
29 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
30 * the function.
31 */
32 TSS2_RC
33 ifapi_eventlog_initialize(
34 IFAPI_EVENTLOG *eventlog,
35 const char *log_dir)
36 {
37 check_not_null(eventlog);
38 check_not_null(log_dir);
39
40 TSS2_RC r;
41
42 r = ifapi_io_check_create_dir(log_dir);
43 return_if_error2(r, "Directory check/creation failed for %s", log_dir);
44
45 eventlog->log_dir = strdup(log_dir);
46 return_if_null(eventlog->log_dir, "Out of memory.", TSS2_FAPI_RC_MEMORY);
47
48 return TSS2_RC_SUCCESS;
49 }
50
51 /** Retrieve the eventlog for a given list of pcrs using asynchronous io.
52 *
53 * Call ifapi_eventlog_get_finish to retrieve the results.
54 *
55 * @param[in,out] eventlog The context area for the eventlog.
56 * @param[in,out] io The context area for the asynchronous io module.
57 * @param[in] pcrList The list of PCR indices to retrieve the log for.
58 * @param[in] pcrListSize The size of pcrList.
59 * @retval TSS2_RC_SUCCESS on success.
60 * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
61 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
62 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
63 * the function.
64 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
65 */
66 TSS2_RC
67 ifapi_eventlog_get_async(
68 IFAPI_EVENTLOG *eventlog,
69 IFAPI_IO *io,
70 const TPM2_HANDLE *pcrList,
71 size_t pcrListSize)
72 {
73 check_not_null(eventlog);
74 check_not_null(io);
75 check_not_null(pcrList);
76
77 if (pcrListSize > TPM2_MAX_PCRS) {
78 LOG_ERROR("pcrList too long %zi > %i", pcrListSize, TPM2_MAX_PCRS);
79 return TSS2_FAPI_RC_BAD_VALUE;
80 }
81
82 LOG_TRACE("called for pcrListSize=%zi", pcrListSize);
83
84 memcpy(&eventlog->pcrList, pcrList, pcrListSize * sizeof(TPM2_HANDLE));
85 eventlog->pcrListSize = pcrListSize;
86 eventlog->pcrListIdx = 0;
87
88 eventlog->log = json_object_new_array();
89 return_if_null(eventlog->log, "Out of memory", TSS2_FAPI_RC_MEMORY);
90
91 return TSS2_RC_SUCCESS;
92 }
93
94 /** Retrieve the eventlog for a given list of pcrs using asynchronous io.
95 *
96 * Call after ifapi_eventlog_get_async.
97 *
98 * @param[in,out] eventlog The context area for the eventlog.
99 * @param[in,out] io The context area for the asynchronous io module.
100 * @param[out] log The event log for the requested PCRs in JSON format
101 * @retval TSS2_RC_SUCCESS on success.
102 * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
103 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
104 * @retval TSS2_FAPI_RC_TRY_AGAIN if the I/O operation is not finished yet and this function needs
105 * to be called again.
106 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
107 * the function.
108 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
109 * operation already pending.
110 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
111 */
112 TSS2_RC
113 ifapi_eventlog_get_finish(
114 IFAPI_EVENTLOG *eventlog,
115 IFAPI_IO *io,
116 char **log)
117 {
118 /* eventlog parameter currently not used */
119 check_not_null(eventlog);
120 check_not_null(io);
121 check_not_null(log);
122
123 TSS2_RC r;
124 char *event_log_file, *logstr;
125 json_object *logpart, *event;
126
127 LOG_TRACE("called");
128
129 loop:
130 /* If we're dune with adding all eventlogs to the json array, we can serialize it and return
131 it to the caller. */
132 if (eventlog->pcrListIdx >= eventlog->pcrListSize) {
133 LOG_TRACE("Done reading pcrLog");
134 *log = strdup(json_object_to_json_string_ext(eventlog->log, JSON_C_TO_STRING_PRETTY));
135 check_oom(*log);
136 json_object_put(eventlog->log);
137 eventlog->log = NULL;
138 eventlog->state = IFAPI_EVENTLOG_STATE_INIT;
139 return TSS2_RC_SUCCESS;
140 }
141
142 switch (eventlog->state) {
143 statecase(eventlog->state, IFAPI_EVENTLOG_STATE_INIT)
144 /* Construct the filename for the eventlog file */
145 r = ifapi_asprintf(&event_log_file, "%s/%s%i",
146 eventlog->log_dir, IFAPI_PCR_LOG_FILE,
147 eventlog->pcrList[eventlog->pcrListIdx]);
148 return_if_error(r, "Out of memory.");
149
150 if (!ifapi_io_path_exists(event_log_file)) {
151 LOG_DEBUG("No event log for pcr %i", eventlog->pcrList[eventlog->pcrListIdx]);
152 SAFE_FREE(event_log_file);
153 eventlog->pcrListIdx += 1;
154 goto loop;
155 }
156
157 /* Initiate the reading of the eventlog file */
158 r = ifapi_io_read_async(io, event_log_file);
159 free(event_log_file);
160 if (r) {
161 LOG_DEBUG("No event log for pcr %i", eventlog->pcrList[eventlog->pcrListIdx]);
162 eventlog->pcrListIdx += 1;
163 goto loop;
164 }
165 fallthrough;
166
167 statecase(eventlog->state, IFAPI_EVENTLOG_STATE_READING)
168 /* Finish the reading of the eventlog file and return it directly to the output parameter */
169 r = ifapi_io_read_finish(io, (uint8_t **)&logstr, NULL);
170 return_try_again(r);
171 return_if_error(r, "read_finish failed");
172
173 logpart = json_tokener_parse(logstr);
174 SAFE_FREE(logstr);
175 return_if_null(log, "JSON parsing error", TSS2_FAPI_RC_BAD_VALUE);
176
177 /* Append the log-entry from logpart to the eventlog */
178 json_type jso_type = json_object_get_type(logpart);
179 if (jso_type != json_type_array) {
180 /* libjson-c does not deliver an array if array has only one element */
181 json_object_array_add(eventlog->log, logpart);
182 } else {
183 /* Iterate through the array of logpart and add each item to the eventlog */
184 /* The return type of json_object_array_length() was changed, thus the case */
185 for (int i = 0; i < (int)json_object_array_length(logpart); i++) {
186 event = json_object_array_get_idx(logpart, i);
187 /* Increment the refcount of event so it does not get freed on put(logpart) below */
188 json_object_get(event);
189 json_object_array_add(eventlog->log, event);
190 }
191 json_object_put(logpart);
192 }
193
194 eventlog->pcrListIdx += 1;
195 eventlog->state = IFAPI_EVENTLOG_STATE_INIT;
196 goto loop;
197
198 statecasedefault(eventlog->state);
199 }
200 return TSS2_RC_SUCCESS;
201 }
202
203 /** Append an event to the existing event log.
204 *
205 * Call ifapi_eventlog_append_finish to finalize this operation.
206 *
207 * @param[in,out] eventlog The context area for the eventlog.
208 * @param[in,out] io The context area for the asynchronous io module.
209 * @param[in] event The event to be appended to the eventlog.
210 * @retval TSS2_RC_SUCCESS on success.
211 * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
212 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
213 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
214 * operation already pending.
215 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
216 */
217 TSS2_RC
218 ifapi_eventlog_append_async(
219 IFAPI_EVENTLOG *eventlog,
220 IFAPI_IO *io,
221 const IFAPI_EVENT *event)
222 {
223 check_not_null(eventlog);
224 check_not_null(io);
225 check_not_null(event);
226
227 TSS2_RC r;
228 char *event_log_file;
229
230 if (eventlog->state != IFAPI_EVENTLOG_STATE_INIT) {
231 LOG_ERROR("Wrong state: %i", eventlog->state);
232 return TSS2_FAPI_RC_BAD_SEQUENCE;
233 }
234
235 eventlog->event = *event;
236
237 /* Construct the filename for the eventlog file */
238 r = ifapi_asprintf(&event_log_file, "%s/%s%i",
239 eventlog->log_dir, IFAPI_PCR_LOG_FILE, event->pcr);
240 return_if_error(r, "Out of memory.");
241
242 /* Initiate the reading of the eventlog file */
243 r = ifapi_io_read_async(io, event_log_file);
244 if (r) {
245 LOG_DEBUG("Eventlog file %s could not be opened, creating...", event_log_file);
246 free(event_log_file);
247 eventlog->state = IFAPI_EVENTLOG_STATE_APPENDING;
248 return TSS2_RC_SUCCESS;
249 }
250 free(event_log_file);
251
252 eventlog->state = IFAPI_EVENTLOG_STATE_READING;
253 return TSS2_RC_SUCCESS;
254 }
255
256 /** Append an event to the existing event log.
257 *
258 * Call after ifapi_eventlog_get_async.
259 *
260 * @param[in,out] eventlog The context area for the eventlog.
261 * @param[in,out] io The context area for the asynchronous io module.
262 * @retval TSS2_RC_SUCCESS on success.
263 * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
264 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
265 * @retval TSS2_FAPI_RC_TRY_AGAIN if the I/O operation is not finished yet and this function needs
266 * to be called again.
267 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
268 * the function.
269 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
270 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
271 * operation already pending.
272 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
273 */
274 TSS2_RC
275 ifapi_eventlog_append_finish(
276 IFAPI_EVENTLOG *eventlog,
277 IFAPI_IO *io)
278 {
279 check_not_null(eventlog);
280 check_not_null(io);
281
282 TSS2_RC r;
283 char *logstr = NULL, *event_log_file;
284 const char *logstr2 = NULL;
285 json_object *log, *event = NULL;
286
287 switch (eventlog->state) {
288 statecase(eventlog->state, IFAPI_EVENTLOG_STATE_READING)
289 /* Finish the reading of the eventlog file and return it directly to the output parameter */
290 r = ifapi_io_read_finish(io, (uint8_t **)&logstr, NULL);
291 return_try_again(r);
292 return_if_error(r, "read_finish failed");
293 fallthrough;
294
295 statecase(eventlog->state, IFAPI_EVENTLOG_STATE_APPENDING)
296 /* If a log was read, we deserialize it to JSON. Otherwise we start a new log. */
297 if (logstr) {
298 log = json_tokener_parse(logstr);
299 SAFE_FREE(logstr);
300 return_if_null(log, "JSON parsing error", TSS2_FAPI_RC_BAD_VALUE);
301
302 /* libjson-c does not deliver an array if array has only one element */
303 json_type jso_type = json_object_get_type(log);
304 if (jso_type != json_type_array) {
305 json_object *json_array = json_object_new_array();
306 json_object_array_add(json_array, log);
307 log = json_array;
308 }
309 } else {
310 log = json_object_new_array();
311 return_if_null(log, "Out of memory", TSS2_FAPI_RC_MEMORY);
312 }
313
314 /* Extend the eventlog with the data */
315 eventlog->event.recnum = json_object_array_length(log) + 1;
316
317 r = ifapi_json_IFAPI_EVENT_serialize(&eventlog->event, &event);
318 if (r) {
319 json_object_put(log);
320 LOG_ERROR("Error serializing event data");
321 return TSS2_FAPI_RC_GENERAL_FAILURE;
322 }
323
324 json_object_array_add(log, event);
325 logstr2 = json_object_to_json_string_ext(log, JSON_C_TO_STRING_PRETTY);
326
327 /* Construct the filename for the eventlog file */
328 r = ifapi_asprintf(&event_log_file, "%s/%s%i",
329 eventlog->log_dir, IFAPI_PCR_LOG_FILE, eventlog->event.pcr);
330 return_if_error(r, "Out of memory.");
331
332 /* Start writing the eventlog back to disk */
333 r = ifapi_io_write_async(io, event_log_file, (uint8_t *) logstr2, strlen(logstr2));
334 free(event_log_file);
335 json_object_put(log); /* this also frees logstr2 */
336 return_if_error(r, "write_async failed");
337 fallthrough;
338
339 statecase(eventlog->state, IFAPI_EVENTLOG_STATE_WRITING)
340 /* Finish writing the eventlog */
341 r = ifapi_io_write_finish(io);
342 return_try_again(r);
343 return_if_error(r, "read_finish failed");
344
345 eventlog->state = IFAPI_EVENTLOG_STATE_INIT;
346 break;
347
348 statecasedefault(eventlog->state);
349 }
350
351 return TSS2_RC_SUCCESS;
352 }
353
354
355 /** Free allocated memory for an ifapi event.
356 *
357 * @param[in,out] event The structure to be cleaned up.
358 */
359 void
360 ifapi_cleanup_event(IFAPI_EVENT * event) {
361 if (event != NULL) {
362 if (event->type == IFAPI_IMA_EVENT_TAG) {
363 SAFE_FREE(event->sub_event.ima_event.eventName);
364 } else if (event->type == IFAPI_TSS_EVENT_TAG) {
365 SAFE_FREE(event->sub_event.tss_event.event);
366 }
367 }
368 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef IFAPI_EVENTLOG_H
6 #define IFAPI_EVENTLOG_H
7
8 #include <json-c/json.h>
9
10 #include "tss2_tpm2_types.h"
11 #include "ifapi_io.h"
12
13 /** Type of event
14 */
15 typedef UINT32 IFAPI_EVENT_TYPE;
16 #define IFAPI_IMA_EVENT_TAG 1 /**< Tag for key resource */
17 #define IFAPI_TSS_EVENT_TAG 2 /**< Tag for key resource */
18
19 /** TSS event information
20 */
21 typedef struct {
22 TPM2B_EVENT data; /**< The event data */
23 char *event; /**< TSS event information */
24 } IFAPI_TSS_EVENT;
25
26 /** IMA event information
27 */
28 typedef struct {
29 TPM2B_DIGEST eventData; /**< The ima event digest */
30 char *eventName; /**< IMA event information */
31 } IFAPI_IMA_EVENT;
32
33 /** Type for representing sub types of FAPI events
34 */
35 typedef union {
36 IFAPI_TSS_EVENT tss_event; /**< TSS event information */
37 IFAPI_IMA_EVENT ima_event; /**< IMA event information */
38 } IFAPI_EVENT_UNION;
39
40 /** Type for representing a FAPI event
41 */
42 typedef struct IFAPI_EVENT {
43 UINT32 recnum; /**< Number of event */
44 TPM2_HANDLE pcr; /**< PCR register */
45 TPML_DIGEST_VALUES digests; /**< The digest list of the event */
46 IFAPI_EVENT_TYPE type; /**< Selector for object type */
47 IFAPI_EVENT_UNION sub_event; /**< Additional event information */
48 } IFAPI_EVENT;
49
50 enum IFAPI_EVENTLOG_STATE {
51 IFAPI_EVENTLOG_STATE_INIT = 0,
52 IFAPI_EVENTLOG_STATE_READING,
53 IFAPI_EVENTLOG_STATE_APPENDING,
54 IFAPI_EVENTLOG_STATE_WRITING
55 };
56
57 typedef struct IFAPI_EVENTLOG {
58 enum IFAPI_EVENTLOG_STATE state;
59 char *log_dir;
60 struct IFAPI_EVENT event;
61 TPM2_HANDLE pcrList[TPM2_MAX_PCRS];
62 size_t pcrListSize;
63 size_t pcrListIdx;
64 json_object *log;
65 } IFAPI_EVENTLOG;
66
67 TSS2_RC
68 ifapi_eventlog_initialize(
69 IFAPI_EVENTLOG *eventlog,
70 const char *log_dir);
71
72 TSS2_RC
73 ifapi_eventlog_get_async(
74 IFAPI_EVENTLOG *eventlog,
75 IFAPI_IO *io,
76 const TPM2_HANDLE *pcrList,
77 size_t pcrListSize);
78
79 TSS2_RC
80 ifapi_eventlog_get_finish(
81 IFAPI_EVENTLOG *eventlog,
82 IFAPI_IO *io,
83 char **log);
84
85 TSS2_RC
86 ifapi_eventlog_append_async(
87 IFAPI_EVENTLOG *eventlog,
88 IFAPI_IO *io,
89 const IFAPI_EVENT *event);
90
91 TSS2_RC
92 ifapi_eventlog_append_finish(
93 IFAPI_EVENTLOG *eventlog,
94 IFAPI_IO *io);
95
96 void
97 ifapi_cleanup_event(
98 IFAPI_EVENT * event);
99
100 #endif /* IFAPI_EVENTLOG_H */
0 /* SPDX-License-Identifier: BSD-3-Clause */
1
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include <stdbool.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include <curl/curl.h>
12 #include <openssl/buffer.h>
13 #include <openssl/evp.h>
14 #include <openssl/sha.h>
15 #include <json-c/json.h>
16
17 #include "fapi_crypto.h"
18 #include "ifapi_helpers.h"
19
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 typedef struct tpm_getekcertificate_ctx tpm_getekcertificate_ctx;
25 struct tpm_getekcertificate_ctx {
26 char *ec_cert_path;
27 FILE *ec_cert_file_handle;
28 char *ek_server_addr;
29 unsigned int SSL_NO_VERIFY;
30 char *ek_path;
31 bool verbose;
32 bool is_tpm2_device_active;
33 TPM2B_PUBLIC *out_public;
34 };
35
36 static tpm_getekcertificate_ctx ctx = {
37 .is_tpm2_device_active = true,
38 };
39
40 /** Compute the SHA256 hash from the public key of an EK.
41 *
42 * @param[in] ek_public The public information of the EK.
43 * @retval unsigned_char* The hash value.
44 * @retval NULL If the computation of the hash fails.
45 */
46 static unsigned char *hash_ek_public(TPM2B_PUBLIC *ek_public) {
47
48 unsigned char *hash = (unsigned char *)malloc(SHA256_DIGEST_LENGTH);
49 if (!hash) {
50 LOG_ERROR("OOM");
51 return NULL;
52 }
53
54 SHA256_CTX sha256;
55 int is_success = SHA256_Init(&sha256);
56 if (!is_success) {
57 LOG_ERROR("SHA256_Init failed");
58 goto err;
59 }
60
61 switch (ek_public->publicArea.type) {
62 case TPM2_ALG_RSA:
63 /* Add public key to the hash. */
64 is_success = SHA256_Update(&sha256,
65 ek_public->publicArea.unique.rsa.buffer,
66 ek_public->publicArea.unique.rsa.size);
67 if (!is_success) {
68 LOG_ERROR("SHA256_Update failed");
69 goto err;
70 }
71
72 /* Add exponent to the hash. */
73 if (ek_public->publicArea.parameters.rsaDetail.exponent != 0) {
74 LOG_ERROR("non-default exponents unsupported");
75 goto err;
76 }
77 /* Exponent 65537 will be added. */
78 BYTE buf[3] = { 0x1, 0x00, 0x01 };
79 is_success = SHA256_Update(&sha256, buf, sizeof(buf));
80 if (!is_success) {
81 LOG_ERROR("SHA256_Update failed");
82 goto err;
83 }
84 break;
85
86 case TPM2_ALG_ECC:
87 is_success = SHA256_Update(&sha256,
88 ek_public->publicArea.unique.ecc.x.buffer,
89 ek_public->publicArea.unique.ecc.x.size);
90 if (!is_success) {
91 LOG_ERROR("SHA256_Update failed");
92 goto err;
93 }
94
95 /* Add public key to the hash. */
96 is_success = SHA256_Update(&sha256,
97 ek_public->publicArea.unique.ecc.y.buffer,
98 ek_public->publicArea.unique.ecc.y.size);
99 if (!is_success) {
100 LOG_ERROR("SHA256_Update failed");
101 goto err;
102 }
103 break;
104
105 default:
106 LOG_ERROR("unsupported EK algorithm");
107 goto err;
108 }
109
110 is_success = SHA256_Final(hash, &sha256);
111 if (!is_success) {
112 LOG_ERROR("SHA256_Final failed");
113 goto err;
114 }
115
116 LOG_TRACE("public-key-hash:");
117 LOG_TRACE(" sha256: ");
118 LOGBLOB_TRACE(&hash[0], SHA256_DIGEST_LENGTH, "Hash");
119 return hash;
120 err:
121 free(hash);
122 return NULL;
123 }
124
125 /** Calculate the base64 encoding of the hash of the Endorsement Public Key.
126 *
127 * @param[in] buffer The hash of the endorsement public key.
128 * @retval char* The base64 encoded string.
129 * @retval NULL if the encoding fails.
130 */
131 static char *
132 base64_encode(const unsigned char* buffer)
133 {
134 BIO *bio, *b64;
135 BUF_MEM *buffer_pointer;
136
137 LOG_INFO("Calculating the base64_encode of the hash of the Endorsement"
138 "Public Key:");
139
140 if (buffer == NULL) {
141 LOG_ERROR("hash_ek_public returned null");
142 return NULL;
143 }
144
145 b64 = BIO_new(BIO_f_base64());
146 bio = BIO_new(BIO_s_mem());
147 bio = BIO_push(b64, bio);
148 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
149 BIO_write(bio, buffer, SHA256_DIGEST_LENGTH);
150 (void)(BIO_flush(bio));
151 BIO_get_mem_ptr(bio, &buffer_pointer);
152
153 /* these are not NULL terminated */
154 char *b64text = buffer_pointer->data;
155 size_t len = buffer_pointer->length;
156
157 size_t i;
158 for (i = 0; i < len; i++) {
159 if (b64text[i] == '+') {
160 b64text[i] = '-';
161 }
162 if (b64text[i] == '/') {
163 b64text[i] = '_';
164 }
165 }
166
167 char *final_string = NULL;
168
169 CURL *curl = curl_easy_init();
170 if (curl) {
171 char *output = curl_easy_escape(curl, b64text, len);
172 if (output) {
173 final_string = strdup(output);
174 curl_free(output);
175 }
176 }
177 curl_easy_cleanup(curl);
178 curl_global_cleanup();
179 BIO_free_all(bio);
180
181 /* format to a proper NULL terminated string */
182 return final_string;
183 }
184
185 /** Decode a base64 encoded certificate into binary form.
186 *
187 * @param[in] buffer The base64 encoded certificate.
188 * @param[in] len The length of the encoded certificate.
189 * @param[out] new_len The lenght of the binary certificate.
190 * @retval char* The binary data of the certificate.
191 * @retval NULL if the decoding fails.
192 */
193 static char *
194 base64_decode(unsigned char* buffer, size_t len, size_t *new_len)
195 {
196 size_t i, unescape_len, r;
197 char *binary_data = NULL, *unescaped_string = NULL;
198
199 LOG_INFO("Decoding the base64 encoded cert into binary form");
200
201 if (buffer == NULL) {
202 LOG_ERROR("Cert buffer is null");
203 return NULL;
204 }
205
206 for (i = 0; i < len; i++) {
207 if (buffer[i] == '-') {
208 buffer[i] = '+';
209 }
210 if (buffer[i] == '_') {
211 buffer[i] = '/';
212 }
213 }
214
215 CURL *curl = curl_easy_init();
216 if (curl) {
217 /* Convert URL encoded string to a "plain string" */
218 char *output = curl_easy_unescape(curl, (char *)buffer,
219 len, (int *)&unescape_len);
220 if (output) {
221 unescaped_string = strdup(output);
222 curl_free(output);
223 }
224 }
225 curl_easy_cleanup(curl);
226 curl_global_cleanup();
227 if (unescaped_string == NULL)
228 return NULL;
229
230 binary_data = calloc(1, unescape_len);
231 if (binary_data == NULL) {
232 free (unescaped_string);
233 return NULL;
234 }
235
236 BIO *bio, *b64;
237 bio = BIO_new_mem_buf(unescaped_string, -1);
238 b64 = BIO_new(BIO_f_base64());
239 bio = BIO_push(b64, bio);
240 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
241
242 if ((r = BIO_read(bio, binary_data, unescape_len)) <= 0) {
243 LOG_ERROR("BIO_read base64 encoded cert failed");
244 free(binary_data);
245 binary_data = NULL;
246 }
247 *new_len = r;
248
249 free (unescaped_string);
250 BIO_free_all(bio);
251 return binary_data;
252 }
253
254 /** Get endorsement certificate from the WEB.
255 *
256 * The base64 encoded public endorsement key will be added to the INTEL
257 * server address and used as URL to retrieve the certificate.
258 * The certificate will be retrieved via curl.
259 *
260 * @param[in] b64h The base64 encoded public key.
261 * @param[out] buffer The json encoded certificate.
262 * @param[out] cert_size The size of the certificate.
263 */
264 int retrieve_endorsement_certificate(char *b64h, unsigned char ** buffer,
265 size_t *cert_size) {
266 int ret = -1;
267
268 size_t len = 1 + strlen(b64h) + strlen(ctx.ek_server_addr);
269 char *weblink = (char *) malloc(len);
270
271 if (!weblink) {
272 LOG_ERROR("oom");
273 return ret;
274 }
275
276 snprintf(weblink, len, "%s%s", ctx.ek_server_addr, b64h);
277
278 CURLcode rc = ifapi_get_curl_buffer((unsigned char *)weblink,
279 buffer, cert_size);
280 free(weblink);
281 return rc;
282 }
283
284 /** Get INTEL certificate for EK
285 *
286 * Using the base64 encoded public endorsement key the JSON encoded certificate
287 * will be downloaded.
288 * The JSON certificate will be parsed and the base64 encoded certificate
289 * will be converted into binary format.
290 *
291 *
292 * @param[in] context The FAPI context with the configuration data.
293 * @param[in] ek_public The out public data of the EK.
294 * @param[out] cert_buffer the der encoded certificate.
295 * @param[out] cert_size The size of the certificate buffer.
296 *
297 * @retval TSS2_RC_SUCCESS on success.
298 * @retval TSS2_FAPI_RC_NO_CERT If an error did occur during certificate downloading.
299 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occured.
300 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
301 */
302 TSS2_RC
303 ifapi_get_intl_ek_certificate(FAPI_CONTEXT *context, TPM2B_PUBLIC *ek_public,
304 unsigned char ** cert_buffer, size_t *cert_size)
305 {
306 int rc = 1;
307 unsigned char *hash = hash_ek_public(ek_public);
308 char *cert_ptr;
309 char *cert_start = NULL, *cert_bin = NULL;
310 char *b64 = base64_encode(hash);
311
312 if (!b64) {
313 LOG_ERROR("base64_encode returned null");
314 goto out;
315 }
316 if (context->config.intel_cert_service)
317 ctx.ek_server_addr = context->config.intel_cert_service;
318 else
319 ctx.ek_server_addr = "https://ekop.intel.com/ekcertservice/";
320
321 LOG_INFO("%s", b64);
322
323 /* Download the JSON encoded certificate. */
324 rc = retrieve_endorsement_certificate(b64, cert_buffer, cert_size);
325 free(b64);
326 goto_if_error(rc, "Retrieve endorsement certificate", out);
327 cert_ptr = (char *)*cert_buffer;
328 LOGBLOB_DEBUG((uint8_t *)cert_ptr, *cert_size, "%s", "Certificate");
329
330 /* Parse certificate data out of the json structure */
331 struct json_object *jso_cert, *jso = json_tokener_parse(cert_ptr);
332 if (jso == NULL)
333 goto_error(rc, TSS2_FAPI_RC_GENERAL_FAILURE,
334 "Failed to parse EK cert data", out_free_json);
335
336 if (!json_object_object_get_ex(jso, "certificate", &jso_cert))
337 goto_error(rc, TSS2_FAPI_RC_GENERAL_FAILURE,
338 "Could not find cert object", out_free_json);
339
340 if (!json_object_is_type(jso_cert, json_type_string))
341 goto_error(rc, TSS2_FAPI_RC_GENERAL_FAILURE,
342 "Invalid EK cert data", out_free_json);
343
344 cert_start = strdup(json_object_get_string(jso_cert));
345 if (!cert_start) {
346 SAFE_FREE(cert_ptr);
347 goto_error(rc, TSS2_FAPI_RC_MEMORY,
348 "Failed to duplicate cert", out_free_json);
349 }
350
351 *cert_size = strlen(cert_start);
352
353 /* Base64 decode buffer into binary PEM format */
354 cert_bin = base64_decode((unsigned char *)cert_start,
355 *cert_size, cert_size);
356 SAFE_FREE(cert_ptr);
357 SAFE_FREE(cert_start);
358
359 if (cert_bin == NULL) {
360 goto_error(rc, TSS2_FAPI_RC_GENERAL_FAILURE,
361 "Invalid EK cert data", out_free_json);
362 }
363 LOG_DEBUG("Binary cert size %zu", *cert_size);
364 *cert_buffer = (unsigned char *)cert_bin;
365
366 out_free_json:
367 json_object_put(jso);
368
369 out:
370 /* In some case this call was necessary after curl usage */
371 OpenSSL_add_all_algorithms();
372
373 free(hash);
374 if (rc == 0) {
375 return TSS2_RC_SUCCESS;
376 } else {
377 LOG_ERROR("Get INTEL EK certificate.");
378 return TSS2_FAPI_RC_NO_CERT;
379 }
380 }
0 /*******************************************************************************
1 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
2 * All rights reserved.
3 ******************************************************************************/
4 #ifndef IFAPI_GET_INTL_CERT_H
5 #define IFAPI_GET_INTL_CERT_H
6
7 TSS2_RC
8 ifapi_get_intl_ek_certificate(
9 FAPI_CONTEXT *context,
10 TPM2B_PUBLIC *ek_public,
11 unsigned char ** buffer,
12 size_t *cert_size);
13
14 #endif /* IFAPI_GET_INTL_CERT_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdarg.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <ctype.h>
19 #include <dirent.h>
20 #include <curl/curl.h>
21
22 #include "tss2_mu.h"
23 #include "fapi_util.h"
24 #include "fapi_policy.h"
25 #include "fapi_crypto.h"
26 #include "ifapi_helpers.h"
27 #include "ifapi_json_serialize.h"
28 #include "ifapi_json_deserialize.h"
29 #include "tpm_json_deserialize.h"
30 #define LOGMODULE fapi
31 #include "util/log.h"
32 #include "util/aux_util.h"
33
34 /** Create template for key creation based on type flags.
35 *
36 * Based on passed flags the TPM2B_PUBLIC data which is used for key
37 * creation will be adapted.
38 *
39 * @param[in] type The flags describing the key type.
40 * @param[in] policy The flag whether a policy is used.
41 * @param[out] template The template including the TPM2B_PUBLIC which will
42 * be used for key creation.
43 * @retval TSS2_RC_SUCCESS if the template can be generated.
44 * @retval TSS2_FAPI_RC_BAD_VALUE If an invalid combination of flags was used.
45 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
46 */
47 TSS2_RC
48 ifapi_set_key_flags(const char *type, bool policy, IFAPI_KEY_TEMPLATE *template)
49 {
50 TSS2_RC r = TSS2_RC_SUCCESS;
51 char *type_dup = NULL;
52 TPMA_OBJECT attributes = 0;
53 UINT32 handle;
54 int pos;
55 bool exportable = false;
56
57 memset(template, 0, sizeof(IFAPI_KEY_TEMPLATE));
58 type_dup = strdup(type);
59 return_if_null(type_dup, "Out of memory.", TSS2_FAPI_RC_MEMORY);
60
61 char *flag = strtok(type_dup, ", ");
62
63 /* The default store will be the user directory */
64 template->system = TPM2_NO;
65
66 /* Loop over all comma or space separated flags */
67 while (flag != NULL) {
68 if (strcasecmp(flag, "system") == 0) {
69 template->system = TPM2_YES;
70 } else if (strcasecmp(flag, "sign") == 0) {
71 attributes |= TPMA_OBJECT_SIGN_ENCRYPT;
72 } else if (strcasecmp(flag, "decrypt") == 0) {
73 attributes |= TPMA_OBJECT_DECRYPT;
74 } else if (strcasecmp(flag, "restricted") == 0) {
75 attributes |= TPMA_OBJECT_RESTRICTED;
76 } else if (strcasecmp(flag, "exportable") == 0) {
77 /* TPMA_OBJECT_ENCRYPTEDDUPLICATION will not be set because no inner
78 symmetric encryption will be used */
79 exportable = true;
80 } else if (strcasecmp(flag, "noda") == 0) {
81 attributes |= TPMA_OBJECT_NODA;
82 } else if (strncmp(flag, "0x", 2) == 0) {
83 sscanf(&flag[2], "%"SCNx32 "%n", &handle, &pos);
84 if ((size_t)pos != strlen(flag) - 2) {
85 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid flag: %s",
86 error, flag);
87 }
88 template->persistent_handle = handle;
89 template->persistent = TPM2_YES;
90 } else {
91 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid flag: %s",
92 error, flag);
93 }
94 flag = strtok(NULL, " ,");
95 }
96 if (exportable) {
97 /* Clear flags preventing duplication */
98 attributes &= ~TPMA_OBJECT_FIXEDTPM;
99 attributes &= ~TPMA_OBJECT_FIXEDPARENT;
100 } else {
101 attributes |= TPMA_OBJECT_FIXEDTPM;
102 attributes |= TPMA_OBJECT_FIXEDPARENT;
103 }
104 /* Set default flags */
105 attributes |= TPMA_OBJECT_SENSITIVEDATAORIGIN;
106 if (!policy)
107 attributes |= TPMA_OBJECT_USERWITHAUTH;
108 else
109 attributes |= TPMA_OBJECT_ADMINWITHPOLICY;
110
111 /* Check whether flags are appropriate */
112 if (attributes & TPMA_OBJECT_RESTRICTED &&
113 attributes & TPMA_OBJECT_SIGN_ENCRYPT &&
114 attributes & TPMA_OBJECT_DECRYPT) {
115 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
116 "Exactly either sign or decrypt must be set.",
117 error);
118 }
119
120 template->public.publicArea.objectAttributes = attributes;
121 SAFE_FREE(type_dup);
122 return TSS2_RC_SUCCESS;
123
124 error:
125 SAFE_FREE(type_dup);
126 return r;
127 }
128
129 /** Create template for nv object creation based on type flags.
130 *
131 * Based on passed flags the TPM2B_NV_PUBLIC data which is used for key
132 * creation will be adapted.
133 * @param[in] type The flags describing the nv object type.
134 * @param[in] policy The flag whether a policy is used.
135 * @param[out] template The template including the TPM2B_NV_PUBLIC which will
136 * be used for nv object creation.
137 * @retval TSS2_RC_SUCCESS if the template can be generated.
138 * @retval TSS2_FAPI_RC_BAD_VALUE If an invalid combination of flags was used.
139 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
140 */
141 TSS2_RC
142 ifapi_set_nv_flags(const char *type, IFAPI_NV_TEMPLATE *template,
143 const char *policy)
144 {
145 TSS2_RC r = TSS2_RC_SUCCESS;
146 char *type_dup = NULL;
147 TPMA_NV attributes = 0;
148 UINT32 handle;
149 int pos;
150 UINT32 size = 0;
151 size_t type_count = 0;
152
153 memset(template, 0, sizeof(IFAPI_NV_TEMPLATE));
154 type_dup = strdup(type);
155 return_if_null(type_dup, "Out of memory.", TSS2_FAPI_RC_MEMORY);
156 /* The default store will be the user directory */
157 template->system = TPM2_NO;
158
159 char *flag = strtok(type_dup, ", ");
160
161 /* Loop over all comma or space separated flags */
162 while (flag != NULL) {
163 if (strcasecmp(flag, "system") == 0) {
164 template->system = TPM2_YES;
165 } else if (strcasecmp(flag, "bitfield") == 0) {
166 attributes |= TPM2_NT_BITS << TPMA_NV_TPM2_NT_SHIFT;
167 type_count += 1;
168 } else if (strcasecmp(flag, "counter") == 0) {
169 attributes |= TPM2_NT_COUNTER << TPMA_NV_TPM2_NT_SHIFT;
170 type_count += 1;
171 } else if (strcasecmp(flag, "pcr") == 0) {
172 attributes |= TPM2_NT_EXTEND << TPMA_NV_TPM2_NT_SHIFT;
173 type_count += 1;
174 } else if (strcasecmp(flag, "noda") == 0) {
175 attributes |= TPMA_NV_NO_DA;
176 } else if (strncmp(flag, "0x", 2) == 0) {
177 sscanf(&flag[2], "%"SCNx32 "%n", &handle, &pos);
178 if ((size_t)pos != strlen(flag) - 2) {
179 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid flag: %s",
180 error, flag);
181 }
182 template->public.nvIndex = handle;
183 } else {
184 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid flag: %s",
185 error, flag);
186 }
187 flag = strtok(NULL, " ,");
188 }
189 if (type_count > 1) {
190 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
191 "Only one type of NV object can be set.", error);
192 }
193 if (type_count == 0) {
194 /* Normal NV space will be defined */
195 attributes |= TPM2_NT_ORDINARY << TPMA_NV_TPM2_NT_SHIFT;
196 if (size == 0)
197 size = 64;
198 }
199 /* If type extend is used the size will be set during the merging of the crypto
200 profile depending on the nameHashAlg stored in the profile.
201 The size of counter and bitfield will be determined by the TPM. */
202
203 if (policy && strlen(policy) > 0) {
204 attributes |= TPMA_NV_POLICYWRITE;
205 attributes |= TPMA_NV_POLICYREAD;
206 } else {
207 attributes |= TPMA_NV_AUTHREAD;
208 attributes |= TPMA_NV_AUTHWRITE;
209 }
210
211 attributes |= TPMA_NV_READ_STCLEAR;
212 attributes |= TPMA_NV_WRITE_STCLEAR;
213 template->public.attributes = attributes;
214 template->hierarchy = TPM2_RH_OWNER;
215 template->public.dataSize = size;
216
217 SAFE_FREE(type_dup);
218 return TSS2_RC_SUCCESS;
219
220 error:
221 SAFE_FREE(type_dup);
222 return r;
223 }
224
225 /** Determine whether path is of certain type.
226 *
227 * @param[in] path The path to be checked.
228 * @param[in] type sub-string at the beginning of the path to be checked.
229 *
230 * @retval true if the path name starts with type.
231 * @retval false if not.
232 */
233 bool
234 ifapi_path_type_p(const char *path, const char *type)
235 {
236 size_t pos = 0;
237 char *end;
238 int end_pos;
239
240 if (strncmp("/", path, 1) == 0)
241 pos = 1;
242 if (strcmp(&path[pos], type) == 0)
243 return true;
244
245 end = strchr(&path[pos], IFAPI_FILE_DELIM_CHAR);
246 if (!end)
247 /* No meaningful path */
248 return false;
249 end_pos = (int)(end - path);
250
251 /* Check sub-string and following delimiter. */
252 if (strlen(path) - pos > 3 &&
253 strncasecmp(type, &path[pos], strlen(type)) == 0 && end &&
254 strncmp(IFAPI_FILE_DELIM, &path[end_pos], 1) == 0)
255 return true;
256 return false;
257 }
258
259 /** Get ESYS handle for a hierarchy path.
260 *
261 * @param[in] path The path to be checked.
262 *
263 * @retval The ESAPI handle for the hierarchy defined in path.
264 * @retval 0 if not handle can be assigned.
265 */
266 ESYS_TR
267 ifapi_get_hierary_handle(const char *path)
268 {
269 int pos = 0;
270
271 if (strncmp("/", path, 1) == 0)
272 pos = 1;
273 if (strcmp(&path[pos], "HE") == 0) {
274 return ESYS_TR_RH_ENDORSEMENT;
275 }
276 if (strcmp(&path[pos], "HS") == 0) {
277 return ESYS_TR_RH_OWNER;
278 }
279 if (strcmp(&path[pos], "LOCKOUT") == 0) {
280 return ESYS_TR_RH_LOCKOUT;
281 }
282 return 0;
283 }
284
285 /** Determine whether path describes a hierarchy object.
286 *
287 * It will be checked whether the path describes a hierarch. A key path
288 * with a hierarchy will not deliver true.
289 *
290 * @param[in] path The path to be checked.
291 *
292 * @retval true if the path describes a hierarchy.
293 * @retval false if not.
294 */
295 bool
296 ifapi_hierarchy_path_p(const char *path)
297 {
298 size_t pos1 = 0;
299 size_t pos2 = 0;
300 char *start;
301
302 if (strncmp("/", path, 1) == 0)
303 pos1 = 1;
304 /* Skip profile if it does exist in path */
305 if (strncmp("P_", &path[pos1], 2) == 0) {
306 start = strchr(&path[pos1], IFAPI_FILE_DELIM_CHAR);
307 if (start) {
308 pos2 = (int)(start - &path[pos1]);
309 if (strncmp("/", &path[pos2], 1) == 0)
310 pos2 += 1;
311 if (strncmp("/", &path[pos2], 1) == 0)
312 pos2 += 1;
313 }
314 }
315 /* Check whether only hierarchy is specified in path */
316 if ((strncasecmp(&path[pos1 + pos2], "HS", 2) == 0 ||
317 strncasecmp(&path[pos1 + pos2], "HE", 2) == 0 ||
318 strncasecmp(&path[pos1 + pos2], "HE", 2) == 0 ||
319 strncasecmp(&path[pos1 + pos2], "HP", 2) == 0 ||
320 strncasecmp(&path[pos1 + pos2], "HN", 2) == 0 ||
321 strncasecmp(&path[pos1 + pos2], "HP", 2) == 0)
322 && (strlen(path) == pos1 + pos2 + 2 ||
323 (strlen(path) == pos1 + pos2 + 3 &&
324 path[pos1 + pos2 + 2] == IFAPI_FILE_DELIM_CHAR))){
325 return true;
326 } else if (strncasecmp(&path[pos1 + pos2], "LOCKOUT", 7) == 0
327 && (strlen(path) == pos1 + pos2 + 7 ||
328 (strlen(path) == pos1 + pos2 + 8 &&
329 path[pos1 + pos2 + 7] == IFAPI_FILE_DELIM_CHAR))) {
330 return true;
331 }
332 return false;
333 }
334
335 /** Compare two variables of type TPM2B_ECC_PARAMETER.
336 *
337 * @param[in] in1 variable to be compared with in2.
338 * @param[in] in2 variable to be compared with in1.
339 *
340 * @retval true if the variables are equal.
341 * @retval false if not.
342 */
343 bool
344 ifapi_TPM2B_ECC_PARAMETER_cmp(TPM2B_ECC_PARAMETER *in1,
345 TPM2B_ECC_PARAMETER *in2)
346 {
347
348 if (in1->size != in2->size)
349 return false;
350
351 return memcmp(&in1->buffer[0], &in2->buffer[0], in1->size) == 0;
352 }
353
354 /** Compare two variables of type TPMS_ECC_POINT.
355 *
356 * @param[in] in1 variable to be compared with in2.
357 * @param[in] in2 variable to be compared with in1.
358 *
359 * @retval true if the variables are equal.
360 * @retval false if not.
361 */
362 bool
363 ifapi_TPMS_ECC_POINT_cmp(TPMS_ECC_POINT *in1, TPMS_ECC_POINT *in2)
364 {
365 LOG_TRACE("call");
366
367 if (!ifapi_TPM2B_ECC_PARAMETER_cmp(&in1->x, &in2->x))
368 return false;
369
370 if (!ifapi_TPM2B_ECC_PARAMETER_cmp(&in1->y, &in2->y))
371 return false;
372
373 return true;
374 }
375
376 /** Compare two variables of type TPM2B_DIGEST.
377 *
378 * @param[in] in1 variable to be compared with in2.
379 * @param[in] in2 variable to be compared with in1.
380 *
381 * @retval true if the variables are equal.
382 * @retval false if not.
383 */
384 bool
385 ifapi_TPM2B_DIGEST_cmp(TPM2B_DIGEST *in1, TPM2B_DIGEST *in2)
386 {
387
388 if (in1->size != in2->size)
389 return false;
390
391 return memcmp(&in1->buffer[0], &in2->buffer[0], in1->size) == 0;
392 }
393
394 /** Compare two variables of type TPM2B_PUBLIC_KEY_RSA.
395 *
396 * @param[in] in1 variable to be compared with in2
397 * @param[in] in2 variable to be compared with in1
398 *
399 * @retval true if the variables are equal.
400 * @retval false if not.
401 */
402 bool
403 ifapi_TPM2B_PUBLIC_KEY_RSA_cmp(TPM2B_PUBLIC_KEY_RSA *in1,
404 TPM2B_PUBLIC_KEY_RSA *in2)
405 {
406
407 if (in1->size != in2->size)
408 return false;
409
410 return memcmp(&in1->buffer[0], &in2->buffer[0], in1->size) == 0;
411 }
412
413 /** Compare two variables of type TPMU_PUBLIC_ID.
414 *
415 * @param[in] in1 variable to be compared with in2.
416 * @param[in] selector1 key type of first key.
417 * @param[in] in2 variable to be compared with in1.
418 * @param[in] selector2 key type of second key.
419 *
420 * @result true if variables are equal.
421 * @result false if not.
422 */
423 bool
424 ifapi_TPMU_PUBLIC_ID_cmp(TPMU_PUBLIC_ID *in1, UINT32 selector1,
425 TPMU_PUBLIC_ID *in2, UINT32 selector2)
426 {
427
428 if (selector1 != selector2)
429 return false;
430
431 switch (selector1) {
432 case TPM2_ALG_KEYEDHASH:
433 if (!ifapi_TPM2B_DIGEST_cmp(&in1->keyedHash, &in2->keyedHash))
434 return false;
435 break;
436 case TPM2_ALG_SYMCIPHER:
437 if (!ifapi_TPM2B_DIGEST_cmp(&in1->sym, &in2->sym))
438 return false;
439 break;
440 case TPM2_ALG_RSA:
441 if (!ifapi_TPM2B_PUBLIC_KEY_RSA_cmp(&in1->rsa, &in2->rsa))
442 return false;
443 break;
444 case TPM2_ALG_ECC:
445 if (!ifapi_TPMS_ECC_POINT_cmp(&in1->ecc, &in2->ecc))
446 return false;
447 break;
448 default:
449 return false;
450 };
451 return true;
452 }
453
454 /**
455 * Compare the PUBLIC_ID stored in two TPMT_PUBLIC structures.
456 * @param[in] in1 the public data with the unique data to be compared with:
457 * @param[in] in2
458 *
459 * @retval true if the variables are equal.
460 * @retval false if not.
461 */
462 bool
463 ifapi_TPMT_PUBLIC_cmp(TPMT_PUBLIC *in1, TPMT_PUBLIC *in2)
464 {
465
466 if (!ifapi_TPMU_PUBLIC_ID_cmp(&in1->unique, in1->type, &in2->unique, in2->type))
467 return false;
468
469 return true;
470 }
471
472 /** Print to allocated string.
473 *
474 * A list of parameters will be printed to an allocated string according to the
475 * format description in the first parameter.
476 *
477 * @param[out] str The allocated output string.
478 * @param[in] fmt The format string (printf formats can be used.)
479 * @param[in] args The list of objects to be printed.
480 *
481 * @retval int The size of the string ff the printing was successful.
482 * @retval -1 if not enough memory can be allocated.
483 */
484 int
485 vasprintf(char **str, const char *fmt, va_list args)
486 {
487 int size = 0;
488 va_list tmpa;
489 char *dmy = NULL;
490 va_copy(tmpa, args);
491 size = vsnprintf(dmy, size, fmt, tmpa);
492 va_end(tmpa);
493 if (size < 0) {
494 return -1;
495 }
496 *str = (char *) malloc(size + 1);
497 if (NULL == *str) {
498 return -1;
499 }
500 size = vsprintf(*str, fmt, args);
501 return size;
502 }
503
504 /** Print to allocated string.
505 *
506 * A list of parameters will be printed to an allocated string according to the
507 * format description in the first parameter.
508 *
509 * @param[out] str The allocated output string.
510 * @param[in] fmt The format string (printf formats can be used.)
511 * @param[in] ... The list of objects to be printed.
512 *
513 * @retval TSS2_RC_SUCCESS If the printing was successful.
514 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
515 */
516 TSS2_RC
517 ifapi_asprintf(char **str, const char *fmt, ...)
518 {
519 int size = 0;
520 va_list args;
521 va_start(args, fmt);
522 size = vasprintf(str, fmt, args);
523 va_end(args);
524 if (size == -1)
525 return TSS2_FAPI_RC_MEMORY;
526 return TSS2_RC_SUCCESS;
527 }
528
529 /** Divides str into substrings based on a delimiter.
530 *
531 * @param[in] string the string to split.
532 * @param[in] delimiter the delimiter.
533 *
534 * @retval The linked list of substrings.
535 * @retval NULL if the list cannot be created.
536 */
537 NODE_STR_T *
538 split_string(const char *string, char *delimiter)
539 {
540 NODE_STR_T *node = NULL;
541 NODE_STR_T *start_node = NULL;
542 char *strtok_save = NULL;
543 char *stringdup = NULL;
544 char *substr = NULL;
545 if (string == NULL)
546 return NULL;
547
548 stringdup = strdup(string);
549 if (stringdup == NULL) {
550 LOG_ERROR("%s", "Out of memory.");
551 goto error_cleanup;
552 }
553 char *stringdup_tokenized = strtok_r(stringdup, delimiter, &strtok_save);
554 if (stringdup_tokenized != NULL) {
555 substr = strdup(stringdup_tokenized);
556 } else {
557 substr = strdup(stringdup);
558 }
559 if (substr == NULL) {
560 LOG_ERROR("%s", "Out of memory.");
561 goto error_cleanup;
562 }
563 do {
564 if (node == NULL) {
565 node = malloc(sizeof(NODE_STR_T));
566 if (node == NULL) {
567 LOG_ERROR("%s", "Out of memory.");
568 goto error_cleanup;
569 }
570 node->next = NULL;
571 node->free_string = true;
572 start_node = node;
573 } else {
574 node->next = malloc(sizeof(NODE_STR_T));
575 if (node->next == NULL) {
576 LOG_ERROR("%s", "Out of memory.");
577 goto error_cleanup;
578 }
579 node = node->next;
580 node->next = NULL;
581 node->free_string = true;
582 }
583 node->str = substr;
584 substr = strtok_r(NULL, delimiter, &strtok_save);
585 if (substr) {
586 substr = strdup(substr);
587 if (substr == NULL) {
588 LOG_ERROR("%s", "Out of memory.");
589 goto error_cleanup;
590 }
591 }
592 } while (substr != NULL);
593
594 SAFE_FREE(stringdup);
595 return start_node;
596 error_cleanup:
597 SAFE_FREE(start_node);
598 SAFE_FREE(substr);
599 SAFE_FREE(stringdup);
600 return NULL;
601 }
602
603 /** Free linked list of strings.
604 *
605 * @param[in] node the first node of the linked list.
606 */
607 void
608 free_string_list(NODE_STR_T *node)
609 {
610 NODE_STR_T *next;
611 if (node == NULL)
612 return;
613 while (node != NULL) {
614 if (node->free_string)
615 free(node->str);
616 next = node->next;
617 free(node);
618 node = next;
619 }
620 }
621
622 /** Free linked list of IFAPI objects.
623 *
624 * @param[in] node the first node of the linked list.
625 */
626 void
627 ifapi_free_object_list(NODE_OBJECT_T *node)
628 {
629 NODE_OBJECT_T *next;
630 if (node == NULL)
631 return;
632 while (node != NULL) {
633 ifapi_cleanup_ifapi_object((IFAPI_OBJECT *)node->object);
634 SAFE_FREE(node->object);
635 next = node->next;
636 free(node);
637 node = next;
638 }
639 }
640
641 /** Free linked list of IFAPI objects (link nodes only).
642 *
643 * @param[in] node the first node of the linked list.
644 */
645 void
646 ifapi_free_node_list(NODE_OBJECT_T *node)
647 {
648 NODE_OBJECT_T *next;
649 if (node == NULL)
650 return;
651 while (node != NULL) {
652 next = node->next;
653 free(node);
654 node = next;
655 }
656 }
657
658 /** Compute the number on nodes in a linked list.
659 *
660 * @param[in] node the first node of the linked list.
661 *
662 * @retval the number on nodes.
663 */
664 size_t
665 ifapi_path_length(NODE_STR_T *node)
666 {
667 size_t length = 0;
668 if (node == NULL)
669 return 0;
670 while (node != NULL) {
671 length += 1;
672 node = node->next;
673 }
674 return length;
675 }
676
677 /** Compute the size of a concatenated string.
678 *
679 * @param[in] node the first node of the linked string list.
680 * @param[in] delim_length the size of the delimiter used for the concatenation.
681 *
682 * @retval the size of the string.
683 */
684 static size_t
685 path_str_length(NODE_STR_T *node, int delim_length)
686 {
687 size_t size = 0;
688 if (node == NULL)
689 return 0;
690 while (node != NULL) {
691 size += strlen(node->str);
692 if (node->next != NULL)
693 size = size + delim_length;
694 node = node->next;
695 }
696 return size;
697 }
698
699 /** Compute a pathname based on a linked list of strings.
700 *
701 * @param[out] dest The pointer to the generated pathname (callee allocated).
702 * @param[in] supdir A sup directory will be the prefix of the pathname.
703 * @param[in] node The linked list.
704 * @param[in] name A name which is appended to the result if not NULL.
705 *
706 * @retval TSS2_RC_SUCCESS if the function call was a success.
707 * @retval TSS2_FAPI_RC_MEMORY if the memory for the pathname can't be allocated.
708 */
709 TSS2_RC
710 ifapi_path_string(char **dest, const char *supdir, NODE_STR_T *node, char *name)
711 {
712 size_t length = 1 + path_str_length(node,
713 1) + ((supdir == NULL) ? 0 : strlen(supdir) + 1)
714 + ((name == NULL) ? 0 : strlen(name) + 1);
715 *dest = malloc(length);
716 if (*dest == NULL) {
717 LOG_ERROR("Out of memory");
718 return TSS2_FAPI_RC_MEMORY;
719 }
720 *dest[0] = '\0';
721 if (supdir != NULL) {
722 strcat(*dest, supdir);
723 strcat(*dest, IFAPI_FILE_DELIM);
724 }
725 for (; node != NULL; node = node->next) {
726 strcat(*dest, node->str);
727 if (node->next != NULL) {
728 strcat(*dest, IFAPI_FILE_DELIM);
729 }
730 }
731 if (name != NULL) {
732 strcat(*dest, IFAPI_FILE_DELIM);
733 strcat(*dest, name);
734 }
735 return TSS2_RC_SUCCESS;
736 }
737
738
739 /** Compute a pathname based on the first n elements of a linked list of strings.
740 *
741 * @param[out] dest the pointer to the pathname (callee allocated).
742 * @param[in] supdir a sup directory will be the prefix of the pathname.
743 * (can be NULL).
744 * @param[in] node the linked list.
745 * @param[in] name the filename (can be NULL).
746 * @param[in] n the number of the first elements which will bes used for concatenation.
747 * @retval TSS2_RC_SUCCESS if the function call was a success.
748 * @retval TSS2_FAPI_RC_MEMORY if the memory for the pathname can't be allocated.
749 */
750 TSS2_RC
751 ifapi_path_string_n(char **dest, const char *supdir, NODE_STR_T *node, char *name,
752 size_t n)
753 {
754 size_t length = 1 + path_str_length(node,
755 1) + ((supdir == NULL) ? 0 : strlen(supdir) + 1)
756 + ((name == NULL) ? 0 : strlen(name) + 1);
757 *dest = malloc(length);
758 size_t i;
759 if (*dest == NULL) {
760 LOG_ERROR("Out of memory");
761 return TSS2_FAPI_RC_MEMORY;
762 }
763 *dest[0] = '\0';
764 if (supdir != NULL) {
765 strcat(*dest, supdir);
766 strcat(*dest, IFAPI_FILE_DELIM);
767 }
768 for (i = 1; node != NULL && i <= n; i++, node = node->next) {
769 strcat(*dest, node->str);
770 if (node->next != NULL) {
771 strcat(*dest, IFAPI_FILE_DELIM);
772 }
773 }
774 if (name != NULL) {
775 strcat(*dest, IFAPI_FILE_DELIM);
776 strcat(*dest, name);
777 }
778 return TSS2_RC_SUCCESS;
779 }
780
781 /** Initialize a linked list of strings.
782 *
783 * free string in the list object will be set to true.
784 * If the list will be extended by sub-string which are part
785 * of this strin free_string has to be set to false.
786 *
787 * @param[in] string The string for the first element.
788 *
789 * @retval the initial node of the linked list.
790 * @retval NULL if the list cannot be created.
791 */
792 NODE_STR_T *
793 init_string_list(const char *string)
794 {
795 NODE_STR_T *result = malloc(sizeof(NODE_STR_T));
796 if (result == NULL)
797 return NULL;
798 result->next = NULL;
799 result->str = strdup(string);
800 if (result->str == NULL) {
801 LOG_ERROR("Out of memory");
802 free(result);
803 return NULL;
804 }
805 result->free_string = true;
806 return result;
807 }
808
809 /** Add string to the last element of a linked list of strings.
810 *
811 * A duplicate of the passed string will be added.
812 *
813 * @param[in,out] str_list The linked list.
814 * @param[in] string The string to be added.
815 *
816 * @retval true if the string was added to the list.
817 * @retval false if the list could not be extended.
818 */
819 bool
820 add_string_to_list(NODE_STR_T *str_list, char *string)
821 {
822 if (str_list == NULL)
823 return NULL;
824 NODE_STR_T *last = malloc(sizeof(NODE_STR_T));
825 if (last == NULL)
826 return false;
827 while (str_list->next != NULL)
828 str_list = str_list->next;
829 str_list->next = last;
830 last->next = NULL;
831 last->str = strdup(string);
832 return_if_null(last->str, "Out of memory.", false);
833 last->free_string = true;
834 return true;
835 }
836
837 /** Add a object as first element to a linked list.
838 *
839 * @param[in] object The object to be added.
840 * @param[in,out] object_list The linked list to be extended.
841 *
842 * @retval TSS2_RC_SUCCESS if the object was added.
843 * @retval TSS2_FAPI_RC_MEMORY If memory for the list extension cannot
844 * be allocated.
845 */
846 TSS2_RC
847 push_object_to_list(void *object, NODE_OBJECT_T **object_list)
848 {
849 NODE_OBJECT_T *first = calloc(1, sizeof(NODE_OBJECT_T));
850 return_if_null(first, "Out of space.", TSS2_FAPI_RC_MEMORY);
851 first->object = object;
852 if (*object_list)
853 first->next = *object_list;
854 *object_list = first;
855 return TSS2_RC_SUCCESS;
856 }
857
858 /** Add a object as last element to a linked list.
859 *
860 * @param[in] object The object to be added.
861 * @param[in,out] object_list The linked list to be extended.
862 *
863 * @retval TSS2_RC_SUCCESS if the object was added.
864 * @retval TSS2_FAPI_RC_MEMORY If memory for the list extension cannot
865 * be allocated.
866 */
867 TSS2_RC
868 append_object_to_list(void *object, NODE_OBJECT_T **object_list)
869 {
870 NODE_OBJECT_T *list, *last = calloc(1, sizeof(NODE_OBJECT_T));
871 return_if_null(last, "Out of space.", TSS2_FAPI_RC_MEMORY);
872 last->object = object;
873 if (!*object_list) {
874 *object_list = last;
875 return TSS2_RC_SUCCESS;
876 }
877 list = *object_list;
878 while (list->next)
879 list = list->next;
880 list->next = last;
881 return TSS2_RC_SUCCESS;
882 }
883
884 /** Initialize the internal representation of a FAPI hierarchy object.
885 *
886 * The object will be cleared and the type of the general fapi object will be
887 * set to hierarchy.
888 *
889 * @param[out] hierarchy The caller allocated hierarchy object.
890 * @param[in] esys_handle The ESAPI handle of the hierarchy which will be added to
891 * to the object.
892 */
893 void
894 ifapi_init_hierarchy_object(
895 IFAPI_OBJECT *hierarchy,
896 ESYS_TR esys_handle)
897 {
898 memset(hierarchy, 0, sizeof(IFAPI_OBJECT));
899 hierarchy->system = TPM2_YES;
900 hierarchy->objectType = IFAPI_HIERARCHY_OBJ;
901 hierarchy->handle = esys_handle;
902 }
903
904 /** Get description of a FAPI object.
905 *
906 * @param[in] object The object which might have a description.
907 *
908 * @retval The character description of the object.
909 * @retval NULL if no description is available.
910 */
911 char *
912 get_description(IFAPI_OBJECT *object)
913 {
914 switch (object->objectType) {
915 case IFAPI_KEY_OBJ:
916 return object->misc.key.description;
917 case IFAPI_NV_OBJ:
918 return object->misc.nv.description;
919 default:
920 return NULL;
921 }
922 }
923
924 /** Create a directory and all sub directories.
925 *
926 * @param[in] supdir The sup directory were the directories will be created.
927 * @param[in] dir_list A linked list with the directory strings.
928 * @param[in] mode The creation mode for the directory which will be used
929 * for the mkdir function.
930 * @retval TSS2_RC_SUCCESS on success.
931 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
932 * the function.
933 */
934 static TSS2_RC
935 create_dirs(const char *supdir, NODE_STR_T *dir_list, mode_t mode)
936 {
937 char *new_dir;
938 for (size_t i = 1; i <= ifapi_path_length(dir_list); i++) {
939 TSS2_RC r = ifapi_path_string_n(&new_dir, supdir, dir_list, NULL, i);
940 return_if_error(r, "Create path string");
941 LOG_TRACE("Check file: %s", new_dir);
942 int rc = mkdir(new_dir, mode);
943 if (rc != 0 && errno != EEXIST) {
944 LOG_ERROR("mkdir not possible: %i %s", rc, new_dir);
945 free(new_dir);
946 return TSS2_FAPI_RC_BAD_VALUE;
947 }
948 free(new_dir);
949 }
950 return TSS2_RC_SUCCESS;
951 }
952
953 /** Create sub-directories in a certain directory.
954 *
955 * @param[in] supdir The directory in which the new directories shall be created.
956 * @param[in] path The path containing one or more sub-directories.
957 *
958 * @retval TSS2_RC_SUCCESS: If the directories were created.
959 * @retval TSS2_FAPI_RC_MEMORY: If the linked list with the sub-directories
960 * cannot be allocated.
961 * @retval TSS2_FAPI_RC_BAD_VALUE: If a directory cannot be created.
962 */
963 TSS2_RC
964 ifapi_create_dirs(const char *supdir, const char *path)
965 {
966 TSS2_RC r;
967 NODE_STR_T *path_list = split_string(path, IFAPI_FILE_DELIM);
968 return_if_null(path_list, "Out of memory.", TSS2_FAPI_RC_MEMORY);
969
970 r = create_dirs(supdir, path_list, 0777);
971 goto_if_error2(r, "Create directories for %s", error_cleanup, path);
972 free_string_list(path_list);
973 return TSS2_RC_SUCCESS;
974
975 error_cleanup:
976 free_string_list(path_list);
977 return r;
978 }
979
980 /** Determine whether authentication with an auth value is needed ro an object..
981 *
982 * In the key store the information whether an auth value was provided for an
983 * object is saved. Thus the it is possible to decide whether the auth value
984 * callback is required for authentication.
985 *
986 * @param[in] object The object which has to be checked..
987 *
988 * @retval true: If an auth value was provided.
989 * @retval false: If not.
990 */
991 bool
992 object_with_auth(IFAPI_OBJECT *object)
993 {
994 switch (object->objectType) {
995 case IFAPI_KEY_OBJ:
996 return (object->misc.key.with_auth == TPM2_YES);
997 case IFAPI_NV_OBJ:
998 return (object->misc.nv.with_auth == TPM2_YES);
999 case IFAPI_HIERARCHY_OBJ:
1000 return (object->misc.hierarchy.with_auth == TPM2_YES);
1001 default:
1002 return false;
1003 }
1004 }
1005
1006 /** Free memory allocated during deserialization of a policy element.
1007 *
1008 * Depending on the element type the fields of a policy element are freed.
1009 *
1010 * @param[in] policy The policy element.
1011 */
1012 static void
1013 cleanup_policy_element(TPMT_POLICYELEMENT *policy)
1014 {
1015 switch (policy->type) {
1016 case POLICYSECRET:
1017 SAFE_FREE(policy->element.PolicySecret.objectPath);
1018 break;
1019 case POLICYAUTHORIZE:
1020 SAFE_FREE(policy->element.PolicyAuthorize.keyPath);
1021 SAFE_FREE(policy->element.PolicyAuthorize.keyPEM);
1022 break;
1023 case POLICYAUTHORIZENV:
1024 SAFE_FREE( policy->element.PolicyAuthorizeNv.nvPath);
1025 SAFE_FREE( policy->element.PolicyAuthorizeNv.policy_buffer);
1026 break;
1027 case POLICYSIGNED:
1028 SAFE_FREE(policy->element.PolicySigned.keyPath);
1029 SAFE_FREE(policy->element.PolicySigned.keyPEM);
1030 SAFE_FREE(policy->element.PolicySigned.publicKeyHint);
1031 break;
1032 case POLICYPCR:
1033 SAFE_FREE(policy->element.PolicyPCR.pcrs);
1034 break;
1035 case POLICYNV:
1036 SAFE_FREE(policy->element.PolicyNV.nvPath);
1037 break;
1038 case POLICYDUPLICATIONSELECT:
1039 SAFE_FREE(policy->element.PolicyDuplicationSelect.newParentPath);
1040 break;
1041 case POLICYNAMEHASH:
1042 for (size_t i = 0; i < 3; i++) {
1043 SAFE_FREE(policy->element.PolicyNameHash.namePaths[i]);
1044 }
1045 break;
1046 case POLICYACTION:
1047 SAFE_FREE(policy->element.PolicyAction.action);
1048 break;
1049 }
1050 }
1051
1052 /** Free memory allocated during deserialization of a a policy element list.
1053 *
1054 * All elements of a policy element list are freed.
1055 *
1056 * @param[in] policy The policy element list.
1057 */
1058 static void
1059 cleanup_policy_elements(TPML_POLICYELEMENTS *policy)
1060 {
1061 size_t i, j;
1062 if (policy != NULL) {
1063 for (i = 0; i < policy->count; i++) {
1064 if (policy->elements[i].type == POLICYOR) {
1065 /* Policy with sub policies */
1066 TPML_POLICYBRANCHES *branches = policy->elements[i].element.PolicyOr.branches;
1067 for (j = 0; j < branches->count; j++) {
1068 SAFE_FREE(branches->authorizations[j].name);
1069 SAFE_FREE(branches->authorizations[j].description);
1070 cleanup_policy_elements(branches->authorizations[j].policy);
1071 }
1072 SAFE_FREE(branches);
1073 } else {
1074 cleanup_policy_element(&policy->elements[i]);
1075 }
1076 }
1077 SAFE_FREE(policy);
1078 }
1079 }
1080
1081 /** Free memory allocated during deserialization of policy.
1082 *
1083 * The object will not be freed (might be declared on the stack).
1084 *
1085 * @param[in] policy The policy to be cleaned up.
1086 *
1087 */
1088 void
1089 ifapi_cleanup_policy(TPMS_POLICY *policy)
1090 {
1091 if (policy) {
1092 SAFE_FREE(policy->description);
1093 if (policy->policyAuthorizations) {
1094 for (size_t i = 0; i < policy->policyAuthorizations->count; i++) {
1095 SAFE_FREE(policy->policyAuthorizations->authorizations[i].type);
1096 }
1097 }
1098 SAFE_FREE(policy->policyAuthorizations);
1099 cleanup_policy_elements(policy->policy);
1100 }
1101 }
1102
1103 /** Free memory of a policy object.
1104 *
1105 * The memory allocated during deserialization of the policy will
1106 * also be freed.
1107 *
1108 * @param[in] object The policy object to be cleaned up.
1109 *
1110 */
1111 static void
1112 cleanup_policy_object(POLICY_OBJECT * object) {
1113 if (object != NULL) {
1114 SAFE_FREE(object->path);
1115 ifapi_cleanup_policy(&object->policy);
1116 cleanup_policy_object(object->next);
1117 }
1118 }
1119
1120 static TPML_POLICYELEMENTS *
1121 copy_policy_elements(const TPML_POLICYELEMENTS *from_policy);
1122
1123 /** Copy policy structure.
1124 *
1125 * @param[in] src The policy structure to be copied.
1126 * @param[out] dest The destination policy structure.
1127 * @retval TSS2_RC_SUCCESS on success.
1128 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1129 */
1130 static TSS2_RC
1131 copy_policy(TPMS_POLICY * dest,
1132 const TPMS_POLICY * src) {
1133 /* Check for NULL references */
1134 if (dest == NULL || src == NULL) {
1135 return TSS2_FAPI_RC_MEMORY;
1136 }
1137
1138 TSS2_RC r = TSS2_RC_SUCCESS;
1139 dest->description = NULL;
1140 strdup_check(dest->description, src->description, r, error_cleanup);
1141 dest->policy = copy_policy_elements(src->policy);
1142 goto_if_null2(dest->policy, "Out of memory", r, TSS2_FAPI_RC_MEMORY,
1143 error_cleanup);
1144
1145 return r;
1146 error_cleanup:
1147 ifapi_cleanup_policy(dest);
1148 return r;
1149 }
1150
1151 /** Copy policy object.
1152 *
1153 * @param[in] src The policy object to be copied.
1154 * @param[out] dest The destination policy object.
1155 * @retval TSS2_RC_SUCCESS on success.
1156 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1157 */
1158 static TSS2_RC
1159 copy_policy_object(POLICY_OBJECT * dest, const POLICY_OBJECT * src) {
1160 /* Check for NULL references */
1161 if (dest == NULL || src == NULL) {
1162 return TSS2_FAPI_RC_MEMORY;
1163 }
1164
1165 TSS2_RC r = TSS2_RC_SUCCESS;
1166 dest->policy.description = NULL;
1167 dest->policy.policyAuthorizations = NULL;
1168 dest->policy.policy = NULL;
1169 strdup_check(dest->path, src->path, r, error_cleanup);
1170 r = copy_policy(&dest->policy, &src->policy);
1171 goto_if_error(r, "Could not copy policy", error_cleanup);
1172 if (src->next != NULL) {
1173 dest->next = malloc(sizeof(POLICY_OBJECT));
1174 goto_if_null(dest->next, "Out of memory", r, error_cleanup);
1175 dest->next->next = NULL;
1176 r = copy_policy_object(dest->next, src->next);
1177 goto_if_error(r, "Could not copy next policy object", error_cleanup);
1178 }
1179
1180 return r;
1181 error_cleanup:
1182 cleanup_policy_object(dest);
1183 return r;
1184 }
1185
1186 /** Copy policy authorization.
1187 *
1188 * @param[in] src The policy authorization to be copied.
1189 * @param[out] dest The destination policy authorization.
1190 * @retval TSS2_RC_SUCCESS on success.
1191 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1192 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1193 */
1194 static TSS2_RC
1195 copy_policyauthorization(TPMS_POLICYAUTHORIZATION * dest,
1196 const TPMS_POLICYAUTHORIZATION * src) {
1197 if (dest == NULL || src == NULL) {
1198 return TSS2_FAPI_RC_BAD_REFERENCE;
1199 }
1200 TSS2_RC r = TSS2_RC_SUCCESS;
1201 strdup_check(dest->type, src->type, r, error_cleanup);
1202
1203 dest->key = src->key;
1204 dest->policyRef = src->policyRef;
1205 dest->signature = src->signature;
1206
1207 return r;
1208 error_cleanup:
1209 SAFE_FREE(dest->type);
1210 return r;
1211 }
1212
1213 /** Copy policy branches.
1214 *
1215 * @param[in] src The policy branches to be copied.
1216 * @param[out] dest The destination policy branches.
1217 * @retval TSS2_RC_SUCCESS on success.
1218 */
1219 static TPML_POLICYBRANCHES *
1220 copy_policy_branches(const TPML_POLICYBRANCHES *from_branches)
1221 {
1222 TPML_POLICYBRANCHES *to_branches;
1223 size_t j;
1224
1225 to_branches = calloc(1, sizeof(TPML_POLICYBRANCHES) +
1226 from_branches->count * sizeof(TPMS_POLICYBRANCH));
1227 if (!to_branches)
1228 return NULL;
1229 to_branches->count = from_branches->count;
1230 for (j = 0; j < from_branches->count; j++) {
1231 to_branches->authorizations[j].name = strdup(from_branches->authorizations[j].name);
1232 if (!to_branches->authorizations[j].name)
1233 goto error;
1234 to_branches->authorizations[j].description =
1235 strdup(from_branches->authorizations[j].description);
1236 if (!to_branches->authorizations[j].description)
1237 goto error;
1238 to_branches->authorizations[j].policy =
1239 copy_policy_elements(from_branches->authorizations[j].policy);
1240 if (to_branches->authorizations[j].policy == NULL
1241 && from_branches->authorizations[j].policy != NULL) {
1242 LOG_ERROR("Out of memory.");
1243 goto error;
1244 }
1245 to_branches->authorizations[j].policyDigests =
1246 from_branches->authorizations[j].policyDigests;
1247 }
1248 return to_branches;
1249
1250 error:
1251 for (j = 0; j < to_branches->count; j++) {
1252 SAFE_FREE(to_branches->authorizations[j].name);
1253 SAFE_FREE(to_branches->authorizations[j].description);
1254 cleanup_policy_elements(to_branches->authorizations[j].policy);
1255 }
1256 SAFE_FREE(to_branches);
1257 return NULL;
1258 }
1259
1260 /** Create a copy of a policy element.
1261 *
1262 * Depending on the type of a poliy element a copy with newly allocated memory will be
1263 * created.
1264 *
1265 * @param[in] from_policy The policy to be copied.
1266 * @param[out] to_policy The new policy element.
1267 *
1268 * @retval TSS2_RC_SUCCESS: if copying was successful.
1269 * @retval TSS2_FAPI_RC_BAD_REFERENCE: If no from policy or no to policy was passed.
1270 * @retval TSS2_FAPI_RC_MEMORY: If not enough memory can be allocated.
1271 */
1272 static TSS2_RC
1273 copy_policy_element(const TPMT_POLICYELEMENT *from_policy, TPMT_POLICYELEMENT *to_policy)
1274 {
1275 if (from_policy == NULL || to_policy == NULL) {
1276 return TSS2_FAPI_RC_BAD_REFERENCE;
1277 }
1278 TSS2_RC r = TSS2_RC_SUCCESS;
1279
1280 *to_policy = *from_policy;
1281 size_t i;
1282
1283 switch (from_policy->type) {
1284 case POLICYSECRET:
1285 strdup_check(to_policy->element.PolicySecret.objectPath,
1286 from_policy->element.PolicySecret.objectPath, r, error);
1287 break;
1288 case POLICYAUTHORIZE:
1289 strdup_check(to_policy->element.PolicyAuthorize.keyPath,
1290 from_policy->element.PolicyAuthorize.keyPath, r, error);
1291 strdup_check(to_policy->element.PolicyAuthorize.keyPEM,
1292 from_policy->element.PolicyAuthorize.keyPEM, r, error);
1293 if (from_policy->element.PolicyAuthorize.policy_list) {
1294 to_policy->element.PolicyAuthorize.policy_list =
1295 malloc(sizeof(POLICY_OBJECT));
1296 goto_if_null2(to_policy->element.PolicyAuthorize.policy_list,
1297 "Out of memory", r, TSS2_FAPI_RC_MEMORY, error);
1298 to_policy->element.PolicyAuthorize.policy_list->next = NULL;
1299 r = copy_policy_object(to_policy->element.PolicyAuthorize.policy_list,
1300 from_policy->element.PolicyAuthorize.policy_list);
1301 goto_if_error(r, "Could not copy policy list", error);
1302
1303 }
1304 if (from_policy->element.PolicyAuthorize.authorization) {
1305 to_policy->element.PolicyAuthorize.authorization =
1306 malloc(sizeof(TPMS_POLICYAUTHORIZATION));
1307 goto_if_null(to_policy->element.PolicyAuthorize.authorization,
1308 "Out of memory", r, error);
1309 r = copy_policyauthorization(to_policy->element.PolicyAuthorize.authorization,
1310 from_policy->element.PolicyAuthorize.authorization);
1311 goto_if_error(r, "Could not copy policy authorization", error);
1312 }
1313 break;
1314 case POLICYAUTHORIZENV:
1315 strdup_check(to_policy->element.PolicyAuthorizeNv.nvPath,
1316 from_policy->element.PolicyAuthorizeNv.nvPath, r, error);
1317 break;
1318 case POLICYSIGNED:
1319 strdup_check(to_policy->element.PolicySigned.keyPath,
1320 from_policy->element.PolicySigned.keyPath, r, error);
1321 strdup_check(to_policy->element.PolicySigned.keyPEM,
1322 from_policy->element.PolicySigned.keyPEM, r, error);
1323 strdup_check(to_policy->element.PolicySigned.publicKeyHint,
1324 from_policy->element.PolicySigned.publicKeyHint, r, error);
1325 break;
1326 case POLICYPCR:
1327 to_policy->element.PolicyPCR.pcrs =
1328 calloc(1, sizeof(TPML_PCRVALUES) +
1329 from_policy->element.PolicyPCR.pcrs->count + sizeof(TPMS_PCRVALUE));
1330 goto_if_null2(to_policy->element.PolicyPCR.pcrs, "Out of memory.",
1331 r, TSS2_FAPI_RC_MEMORY, error);
1332 to_policy->element.PolicyPCR.pcrs->count
1333 = from_policy->element.PolicyPCR.pcrs->count;
1334 for (i = 0; i < to_policy->element.PolicyPCR.pcrs->count; i++)
1335 to_policy->element.PolicyPCR.pcrs->pcrs[i]
1336 = from_policy->element.PolicyPCR.pcrs->pcrs[i];
1337 break;
1338 case POLICYNV:
1339 strdup_check(to_policy->element.PolicyNV.nvPath,
1340 from_policy->element.PolicyNV.nvPath, r, error);
1341 break;
1342 case POLICYDUPLICATIONSELECT:
1343 strdup_check(to_policy->element.PolicyDuplicationSelect.newParentPath,
1344 from_policy->element.PolicyDuplicationSelect.newParentPath,
1345 r, error);
1346 break;
1347 case POLICYNAMEHASH:
1348 for (size_t i = 0; i < from_policy->element.PolicyNameHash.count; i++) {
1349 strdup_check(to_policy->element.PolicyNameHash.namePaths[i],
1350 from_policy->element.PolicyNameHash.namePaths[i],
1351 r, error);
1352 }
1353 break;
1354 case POLICYOR:
1355 to_policy->element.PolicyOr.branches =
1356 copy_policy_branches(from_policy->element.PolicyOr.branches);
1357 goto_if_null2(to_policy->element.PolicyOr.branches, "Out of memory",
1358 r, TSS2_FAPI_RC_MEMORY, error);
1359 break;
1360 }
1361 return TSS2_RC_SUCCESS;
1362
1363 error:
1364 return r;
1365 }
1366
1367 /** Copy a list of policy elements
1368 *
1369 * @param[in] form_policy The policy list to be copied.
1370 * @retval NULL If the policy cannot be copied.
1371 * @retval TPML_POLICYELEMENTS The copy of the policy list.
1372 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1373 */
1374 static TPML_POLICYELEMENTS *
1375 copy_policy_elements(const TPML_POLICYELEMENTS *from_policy)
1376 {
1377 if (from_policy == NULL) {
1378 return NULL;
1379 }
1380 TSS2_RC r;
1381 size_t i;
1382 TPML_POLICYELEMENTS *to_policy = NULL;
1383
1384 to_policy = calloc(1, sizeof(TPML_POLICYELEMENTS) +
1385 from_policy->count * sizeof(TPMT_POLICYELEMENT));
1386 to_policy->count = from_policy->count;
1387 for (i = 0; i < from_policy->count; i++) {
1388 if (from_policy->elements[i].type == POLICYOR) {
1389 to_policy->elements[i].type = POLICYOR;
1390 /* Policy with sub policies */
1391 TPML_POLICYBRANCHES *branches = from_policy->elements[i].element.PolicyOr.branches;
1392 to_policy->elements[i].element.PolicyOr.branches = copy_policy_branches(branches);
1393 if (to_policy->elements[i].element.PolicyOr.branches == NULL) {
1394 LOG_ERROR("Out of memory");
1395 SAFE_FREE(to_policy);
1396 return NULL;
1397 }
1398 } else {
1399 r = copy_policy_element(&from_policy->elements[i], &to_policy->elements[i]);
1400 if (r != TSS2_RC_SUCCESS) {
1401 cleanup_policy_elements(to_policy);
1402 return NULL;
1403 }
1404 }
1405 }
1406 return to_policy;
1407 }
1408
1409 /** Copy policy.
1410 *
1411 * @param[in] from_policy the policy to be copied.
1412 * @retval The new policy or NULL if not enough memory was available.
1413 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1414 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1415 */
1416 TPMS_POLICY *
1417 ifapi_copy_policy(
1418 const TPMS_POLICY *from_policy)
1419 {
1420 if (from_policy == NULL) {
1421 return NULL;
1422 }
1423 TPMS_POLICY *to_policy = calloc(1, sizeof(TPMS_POLICY));
1424 if (to_policy == NULL) {
1425 return NULL;
1426 }
1427 to_policy->description = NULL;
1428 TSS2_RC r = copy_policy(to_policy, from_policy);
1429 if (r != TSS2_RC_SUCCESS) {
1430 SAFE_FREE(to_policy);
1431 return NULL;
1432 } else {
1433 return to_policy;
1434 }
1435 }
1436
1437 /** Compute the name of a TPM transient or persistent object.
1438 *
1439 * @param[in] publicInfo The public information of the TPM object.
1440 * @param[out] name The computed name.
1441 * @retval TPM2_RC_SUCCESS or one of the possible errors TSS2_FAPI_RC_BAD_VALUE,
1442 * TSS2_FAPI_RC_MEMORY, TSS2_FAPI_RC_GENERAL_FAILURE.
1443 * or return codes of SAPI errors.
1444 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1445 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1446 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1447 * the function.
1448 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1449 */
1450 TSS2_RC
1451 ifapi_get_name(TPMT_PUBLIC *publicInfo, TPM2B_NAME *name)
1452 {
1453 BYTE buffer[sizeof(TPMT_PUBLIC)];
1454 size_t offset = 0;
1455 size_t len_alg_id = sizeof(TPMI_ALG_HASH);
1456 size_t size = sizeof(TPMU_NAME) - sizeof(TPMI_ALG_HASH);
1457 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext;
1458
1459 if (publicInfo->nameAlg == TPM2_ALG_NULL) {
1460 name->size = 0;
1461 return TSS2_RC_SUCCESS;
1462 }
1463 TSS2_RC r;
1464 r = ifapi_crypto_hash_start(&cryptoContext, publicInfo->nameAlg);
1465 return_if_error(r, "crypto hash start");
1466
1467 r = Tss2_MU_TPMT_PUBLIC_Marshal(publicInfo,
1468 &buffer[0], sizeof(TPMT_PUBLIC), &offset);
1469 if (r) {
1470 LOG_ERROR("Marshaling TPMT_PUBLIC");
1471 ifapi_crypto_hash_abort(&cryptoContext);
1472 return r;
1473 }
1474
1475 r = ifapi_crypto_hash_update(cryptoContext, &buffer[0], offset);
1476 if (r) {
1477 LOG_ERROR("crypto hash update");
1478 ifapi_crypto_hash_abort(&cryptoContext);
1479 return r;
1480 }
1481
1482 r = ifapi_crypto_hash_finish(&cryptoContext, &name->name[len_alg_id],
1483 &size);
1484 if (r) {
1485 LOG_ERROR("crypto hash finish");
1486 ifapi_crypto_hash_abort(&cryptoContext);
1487 return r;
1488 }
1489
1490 offset = 0;
1491 r = Tss2_MU_TPMI_ALG_HASH_Marshal(publicInfo->nameAlg,
1492 &name->name[0], sizeof(TPMI_ALG_HASH),
1493 &offset);
1494 return_if_error(r, "Marshaling TPMI_ALG_HASH");
1495
1496 name->size = size + len_alg_id;
1497 return TSS2_RC_SUCCESS;
1498 }
1499
1500 /** Compute the name from the public data of a NV index.
1501 *
1502 * The name of a NV index is computed as follows:
1503 * name = nameAlg||Hash(nameAlg,marshal(publicArea))
1504 * @param[in] publicInfo The public information of the NV index.
1505 * @param[out] name The computed name.
1506 * @retval TSS2_RC_SUCCESS on success.
1507 * @retval TSS2_FAPI_RC_MEMORY Memory can not be allocated.
1508 * @retval TSS2_FAPI_RC_BAD_VALUE for invalid parameters.
1509 * @retval TSS2_FAPI_RC_BAD_REFERENCE for unexpected NULL pointer parameters.
1510 * @retval TSS2_FAPI_RC_GENERAL_FAILURE for errors of the crypto library.
1511 * @retval TSS2_SYS_RC_* for SAPI errors.
1512 */
1513 TSS2_RC
1514 ifapi_nv_get_name(TPM2B_NV_PUBLIC *publicInfo, TPM2B_NAME *name)
1515 {
1516 BYTE buffer[sizeof(TPMS_NV_PUBLIC)];
1517 size_t offset = 0;
1518 size_t size = sizeof(TPMU_NAME) - sizeof(TPMI_ALG_HASH);
1519 size_t len_alg_id = sizeof(TPMI_ALG_HASH);
1520 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext;
1521
1522 if (publicInfo->nvPublic.nameAlg == TPM2_ALG_NULL) {
1523 name->size = 0;
1524 return TSS2_RC_SUCCESS;
1525 }
1526 TSS2_RC r;
1527
1528 /* Initialize the hash computation with the nameAlg. */
1529 r = ifapi_crypto_hash_start(&cryptoContext, publicInfo->nvPublic.nameAlg);
1530 return_if_error(r, "Crypto hash start");
1531
1532 /* Get the marshaled data of the public area. */
1533 r = Tss2_MU_TPMS_NV_PUBLIC_Marshal(&publicInfo->nvPublic,
1534 &buffer[0], sizeof(TPMS_NV_PUBLIC),
1535 &offset);
1536 if (r) {
1537 LOG_ERROR("Marshaling TPMS_NV_PUBLIC");
1538 ifapi_crypto_hash_abort(&cryptoContext);
1539 return r;
1540 }
1541
1542 r = ifapi_crypto_hash_update(cryptoContext, &buffer[0], offset);
1543 if (r) {
1544 LOG_ERROR("crypto hash update");
1545 ifapi_crypto_hash_abort(&cryptoContext);
1546 return r;
1547 }
1548
1549 /* The hash will be stored after the nameAlg.*/
1550 r = ifapi_crypto_hash_finish(&cryptoContext, &name->name[len_alg_id],
1551 &size);
1552 if (r) {
1553 LOG_ERROR("crypto hash finish");
1554 ifapi_crypto_hash_abort(&cryptoContext);
1555 return r;
1556 }
1557
1558 offset = 0;
1559 /* Store the nameAlg in the result. */
1560 r = Tss2_MU_TPMI_ALG_HASH_Marshal(publicInfo->nvPublic.nameAlg,
1561 &name->name[0], sizeof(TPMI_ALG_HASH),
1562 &offset);
1563 return_if_error(r, "Marshaling TPMI_ALG_HASH");
1564
1565 name->size = size + len_alg_id;
1566 return TSS2_RC_SUCCESS;
1567 }
1568
1569 /** Check whether a nv or key object has a certain name.
1570 *
1571 * @param[in] object The object (has to be checked whether it's a key).
1572 * @param[in] name The name to be compared.
1573 * @param[out] equal If the two names are equal.
1574 * @retval TSS2_RC_SUCCESSS if name of object can be deserialized.
1575 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1576 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1577 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1578 * the function.
1579 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1580 */
1581 TSS2_RC
1582 ifapi_object_cmp_name(IFAPI_OBJECT *object, void *name, bool *equal)
1583 {
1584 TSS2_RC r;
1585 *equal = false;
1586 TPM2B_NAME *obj_name;
1587 TPM2B_NAME nv_name;
1588
1589 switch (object->objectType) {
1590 case IFAPI_KEY_OBJ:
1591 obj_name = &object->misc.key.name;
1592 break;
1593 case IFAPI_NV_OBJ:
1594 r = ifapi_nv_get_name(&object->misc.nv.public, &nv_name);
1595 return_if_error(r, "Get NV name.");
1596
1597 obj_name = &nv_name;
1598 break;
1599 default:
1600 return TSS2_RC_SUCCESS;
1601 }
1602 if (obj_name->size != ((TPM2B_NAME *)name)->size)
1603 return TSS2_RC_SUCCESS;
1604 if (memcmp(&obj_name->name[0], &((TPM2B_NAME *)name)->name[0], obj_name->size))
1605 /* The names are not equal */
1606 return TSS2_RC_SUCCESS;
1607 /* The two names are equal */
1608 *equal = true;
1609 return TSS2_RC_SUCCESS;
1610 }
1611
1612 /** Check whether a nv object has a certain public info.
1613 *
1614 * @param[in] object The object (has to be checked whether it's a key).
1615 * @param[in] nv_public The NV public data with the NV index.
1616 * @param[out] equal If the two names are equal.
1617 * @retval TSS2_RC_SUCCESSS if name of object can be deserialized.
1618 */
1619 TSS2_RC
1620 ifapi_object_cmp_nv_public(IFAPI_OBJECT *object, void *nv_public, bool *equal)
1621 {
1622 *equal = false;
1623
1624 switch (object->objectType) {
1625 break;
1626 case IFAPI_NV_OBJ:
1627 if (object->misc.nv.public.nvPublic.nvIndex
1628 == ((TPM2B_NV_PUBLIC *)nv_public)->nvPublic.nvIndex)
1629 *equal = true;
1630 break;
1631 default:
1632 return TSS2_RC_SUCCESS;
1633 }
1634 return TSS2_RC_SUCCESS;
1635 }
1636
1637 /** Compute signature as byte array and signature size in DER format.
1638 *
1639 * For ECC signatures the conversion to DER is necessary, for RSA the
1640 * buffer of the TPM2B has already DER format.
1641 * parameters.
1642 * @param[in] sig_key_object The signing key.
1643 * @param[in] tpm_signature the signature in TPM format.
1644 * @param[out] signature The byte array of the signature (callee allocated).
1645 * @param[out] signatureSize The size of the byte array.
1646 *
1647 * @retval TSS2_RC_SUCCESSS if the conversion was successful.
1648 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
1649 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
1650 * not covered by other return codes (e.g. a unexpected openssl
1651 * error).
1652 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1653 * the function.
1654 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1655 */
1656 TSS2_RC
1657 ifapi_tpm_to_fapi_signature(
1658 IFAPI_OBJECT *sig_key_object,
1659 TPMT_SIGNATURE *tpm_signature,
1660 uint8_t **signature,
1661 size_t *signatureSize)
1662 {
1663 TSS2_RC r;
1664
1665 *signature = NULL;
1666 TPMT_SIG_SCHEME *sig_scheme = &sig_key_object->misc.key.signing_scheme;
1667
1668 if (sig_key_object->misc.key.public.publicArea.type == TPM2_ALG_RSA) {
1669 /* Signature is already in DER format. */
1670
1671 if (sig_scheme->scheme == TPM2_ALG_RSAPSS) {
1672 *signatureSize = tpm_signature->signature.rsapss.sig.size;
1673 *signature = malloc(*signatureSize);
1674 goto_if_null(*signature, "Out of memory.", TSS2_FAPI_RC_MEMORY, error_cleanup);
1675
1676 memcpy(*signature,
1677 &tpm_signature->signature.rsapss.sig.buffer[0],
1678 *signatureSize);
1679 } else if (sig_scheme->scheme == TPM2_ALG_RSASSA) {
1680 *signatureSize = tpm_signature->signature.rsassa.sig.size;
1681 *signature = malloc(*signatureSize);
1682 goto_if_null(*signature, "Out of memory.", TSS2_FAPI_RC_MEMORY, error_cleanup);
1683
1684 memcpy(*signature,
1685 &tpm_signature->signature.rsassa.sig.buffer[0],
1686 *signatureSize);
1687 }
1688 } else if (sig_key_object->misc.key.public.publicArea.type == TPM2_ALG_ECC &&
1689 sig_scheme->scheme == TPM2_ALG_ECDSA) {
1690 /* For ECC signatures the TPM signaute has to be converted to DER. */
1691 r = ifapi_tpm_ecc_sig_to_der(tpm_signature,
1692 signature, signatureSize);
1693 goto_if_error(r, "Conversion to DER failed", error_cleanup);
1694 } else {
1695 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Unknown signature scheme", error_cleanup);
1696 }
1697 return TSS2_RC_SUCCESS;
1698
1699 error_cleanup:
1700 SAFE_FREE(*signature);
1701 return r;
1702 }
1703
1704 /** Compute the JSON representation of quote information.
1705 *
1706 * The attest generated by a TPM quote will be converted into a
1707 * JSON representation together with the signature scheme of the
1708 * key used for the quote.
1709 *
1710 * @param[in] sig_key_object The key object which was used for the quote.
1711 * @param[in] tpm_quoted: The attest produced by the quote.
1712 * @param[out] quoteInfo The character string with the JSON representation of the
1713 * attest together with the signing schemed.
1714 *
1715 * @retval TSS2_RC_SUCCESS: If the conversion was successful.
1716 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
1717 * @retval TSS2_FAPI_RC_BAD_VALUE: If an invalid value is detected during
1718 * serialisation.
1719 * @retval Possible error codes of the unmarshaling function.
1720 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1721 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1722 */
1723 TSS2_RC
1724 ifapi_compute_quote_info(
1725 IFAPI_OBJECT *sig_key_object,
1726 TPM2B_ATTEST *tpm_quoted,
1727 char **quoteInfo)
1728 {
1729 json_object *jso = NULL;
1730 TSS2_RC r;
1731 size_t offset = 0;
1732 TPMS_ATTEST attest_struct;
1733 FAPI_QUOTE_INFO fapi_quote_info;
1734
1735 /* The TPM2B_ATTEST contains the marshaled TPMS_ATTEST structure. */
1736 r = Tss2_MU_TPMS_ATTEST_Unmarshal((const uint8_t *)
1737 &tpm_quoted->attestationData[0],
1738 tpm_quoted->size, &offset, &attest_struct);
1739 return_if_error(r, "Unmarshal TPMS_ATTEST.");
1740
1741 fapi_quote_info.attest = attest_struct;
1742 /* The signate scheme will be taken from the key used for qoting. */
1743 fapi_quote_info.sig_scheme = sig_key_object->misc.key.signing_scheme;
1744 r = ifapi_json_FAPI_QUOTE_INFO_serialize(&fapi_quote_info, &jso);
1745 return_if_error(r, "Conversion to TPM2B_ATTEST to JSON.");
1746
1747 /* The intermediate structure of type FAPI_QOTE_INFO will be serialized. */
1748 const char *quote_json = json_object_to_json_string_ext(jso,
1749 JSON_C_TO_STRING_PRETTY);
1750 goto_if_null(quote_json, "Conversion attest to json.",
1751 TSS2_FAPI_RC_GENERAL_FAILURE, cleanup);
1752
1753 *quoteInfo = strdup(quote_json);
1754 goto_if_null(*quoteInfo, "Out of memory.", TSS2_FAPI_RC_MEMORY, cleanup);
1755
1756 cleanup:
1757 json_object_put(jso);
1758 return r;
1759 }
1760
1761 /** Deserialize the JSON representation of FAPI quote information.
1762 *
1763 * The JSON representation of FAPI quote information will be
1764 * deserialized to a FAPI_QUOTE_INFO structure and also the TPM2B
1765 * version of the attest will be created.
1766 *
1767 * @param[in] quoteInfo The JSON representation if the quote
1768 * information.
1769 * @param[out] tpm_quoted: The marhaled version of the attest structure.
1770 * @param[out] fapi_quote_info The quote information structure used by
1771 * FAPI.
1772 *
1773 * @retval TSS2_RC_SUCCESS: If the deserialization was successful.
1774 * @retval TSS2_FAPI_RC_BAD_VALUE: If an invalid value is detected during
1775 * deserialisation.
1776 * @retval Possible error codes of the marshaling function.
1777 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1778 */
1779 TSS2_RC
1780 ifapi_get_quote_info(
1781 char const *quoteInfo,
1782 TPM2B_ATTEST *tpm_quoted,
1783 FAPI_QUOTE_INFO *fapi_quote_info)
1784 {
1785 json_object *jso = NULL;
1786 TSS2_RC r;
1787 size_t offset = 0;
1788
1789 jso = json_tokener_parse(quoteInfo);
1790 return_if_null(jso, "Json error.", TSS2_FAPI_RC_BAD_VALUE);
1791
1792 memset(&fapi_quote_info->attest.attested.quote.pcrSelect, 0,
1793 sizeof(TPML_PCR_SELECTION));
1794
1795 r = ifapi_json_FAPI_QUOTE_INFO_deserialize(jso, fapi_quote_info);
1796 goto_if_error(r, "Conversion to JSON of TPM2S_ATTEST.", cleanup);
1797
1798 offset = 0;
1799 r = Tss2_MU_TPMS_ATTEST_Marshal(&fapi_quote_info->attest,
1800 (uint8_t *)&tpm_quoted->attestationData[0],
1801 sizeof(TPMS_ATTEST), &offset);
1802 LOGBLOB_TRACE(&tpm_quoted->attestationData[0],
1803 offset,
1804 "Attest");
1805 tpm_quoted-> size = offset;
1806 goto_if_error(r, "Marshal attest.", cleanup);
1807
1808 cleanup:
1809 if (jso)
1810 json_object_put(jso);
1811 return r;
1812 }
1813
1814 /** Determine start index for NV object depending on type.
1815 *
1816 * The value will be determined based on e TCG handle registry.
1817 *
1818 * @param[in] path The path used for the NV object.
1819 * @param[out] start_nv_index The first possible NV index for this type.
1820 *
1821 * @retval TSS2_RC_SUCCESS If the index for the path can be determined.
1822 * @retval TSS2_FAPI_RC_BAD_PATH If no handle can be assigned.
1823 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1824 */
1825 TSS2_RC
1826 ifapi_get_nv_start_index(const char *path, TPM2_HANDLE *start_nv_index)
1827 {
1828 NODE_STR_T *dir_list = split_string(path, IFAPI_FILE_DELIM);
1829
1830 *start_nv_index = 0;
1831
1832 return_if_null(dir_list, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1833 if (dir_list->next && strcmp(dir_list->str, "nv") == 0) {
1834 if (strcmp(dir_list->next->str, "TPM") == 0)
1835 *start_nv_index = 0x01000000;
1836 else if (strcmp(dir_list->next->str, "Platform") == 0)
1837 *start_nv_index = 0x01400000;
1838 else if (strcmp(dir_list->next->str, "Owner") == 0)
1839 *start_nv_index = 0x01800000;
1840 else if (strcmp(dir_list->next->str, "Endorsement_Certificate") == 0)
1841 *start_nv_index = 0x01c00000;
1842 else if (strcmp(dir_list->next->str, "Platform_Certificate") == 0)
1843 *start_nv_index = 0x01c80000;
1844 else if (strcmp(dir_list->next->str, "Component_OEM") == 0)
1845 *start_nv_index = 0x01c10000;
1846 else if (strcmp(dir_list->next->str, "TPM_OEM") == 0)
1847 *start_nv_index = 0x01c20000;
1848 else if (strcmp(dir_list->next->str, "Platform_OEM") == 0)
1849 *start_nv_index = 0x01c30000;
1850 else if (strcmp(dir_list->next->str, "PC-Client") == 0)
1851 *start_nv_index = 0x01c40000;
1852 else if (strcmp(dir_list->next->str, "Sever") == 0)
1853 *start_nv_index = 0x01c50000;
1854 else if (strcmp(dir_list->next->str, "Virtualized_Platform") == 0)
1855 *start_nv_index = 0x01c60000;
1856 else if (strcmp(dir_list->next->str, "MPWG") == 0)
1857 *start_nv_index = 0x01c70000;
1858 else if (strcmp(dir_list->next->str, "Embedded") == 0)
1859 *start_nv_index = 0x01c80000;
1860 }
1861 free_string_list(dir_list);
1862 if (*start_nv_index)
1863 return TSS2_RC_SUCCESS;
1864
1865 return_error2(TSS2_FAPI_RC_BAD_PATH, "Invalid NV path: %s", path);
1866 }
1867
1868 /** Compute new PCR value from a part of an event list.
1869 *
1870 * @param[in,out] vpcr The old and the new PCR value.
1871 * @param[in] bank The bank corresponding to value of the event list
1872 * which will be used for computation.
1873 * @param[in] event The event list with the values which were extended
1874 * for a certain bank.
1875 * @retval TSS2_FAPI_RC_BAD_VALUE if the bank was not found in the event list.
1876 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an error occurs in the crypto library
1877 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1878 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1879 */
1880 TSS2_RC
1881 ifapi_extend_vpcr(
1882 TPM2B_DIGEST *vpcr,
1883 TPMI_ALG_HASH bank,
1884 const IFAPI_EVENT *event)
1885 {
1886 TSS2_RC r;
1887 size_t i;
1888 size_t event_size, size;
1889 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext;
1890
1891 LOGBLOB_TRACE(&vpcr->buffer[0], vpcr->size, "Old vpcr value");
1892
1893 for (i = 0; i < event->digests.count; i++) {
1894 if (event->digests.digests[i].hashAlg == bank) {
1895 event_size = ifapi_hash_get_digest_size(event->digests.digests[i].hashAlg);
1896
1897 LOGBLOB_TRACE(&event->digests.digests[i].digest.sha512[0], event_size,
1898 "Extending with");
1899
1900 r = ifapi_crypto_hash_start(&cryptoContext, bank);
1901 return_if_error(r, "crypto hash start");
1902
1903 HASH_UPDATE_BUFFER(cryptoContext, &vpcr->buffer[0], vpcr->size, r, error_cleanup);
1904 HASH_UPDATE_BUFFER(cryptoContext, &event->digests.digests[i].digest.sha512[0],
1905 event_size, r, error_cleanup);
1906 r = ifapi_crypto_hash_finish(&cryptoContext, &vpcr->buffer[0], &size);
1907 return_if_error(r, "crypto hash finish");
1908 vpcr->size = size;
1909 break;
1910 }
1911 }
1912 if (i == event->digests.count) {
1913 LOG_ERROR("No digest for bank %"PRIu16" found in event", bank);
1914 return TSS2_FAPI_RC_BAD_VALUE;
1915 }
1916 LOGBLOB_TRACE(&vpcr->buffer[0], vpcr->size, "New vpcr value");
1917
1918 return TSS2_RC_SUCCESS;
1919
1920 error_cleanup:
1921 ifapi_crypto_hash_abort(&cryptoContext);
1922 return r;
1923 }
1924
1925 /** Check whether a event list corresponds to a certain quote information.
1926 *
1927 * The event list is used to compute the PCR values corresponding
1928 * to this event list. The PCR digest for these PCRs is computed and compared
1929 * with the attest passed with quote_info.
1930 *
1931 * @param[in] jso_event_list The event list in JSON representation.
1932 * @param[in] quote_info The information structure with the attest.
1933 * @param[out] pcr_digest The computed pcr_digest for the PCRs uses by FAPI.
1934 *
1935 * @retval TSS2_RC_SUCCESS: If the PCR digest from the event list matches
1936 * the PCR digest passed with the quote_info.
1937 * @retval TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED: If the digest computed
1938 * from event list does not match the attest
1939 * @retval TSS2_FAPI_RC_BAD_VALUE: If inappropriate values are detected in the
1940 * input data.
1941 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1942 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1943 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1944 */
1945 TSS2_RC
1946 ifapi_calculate_pcr_digest(
1947 json_object *jso_event_list,
1948 const FAPI_QUOTE_INFO *quote_info,
1949 TPM2B_DIGEST *pcr_digest)
1950 {
1951 TSS2_RC r;
1952 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
1953
1954 struct {
1955 TPMI_ALG_HASH bank;
1956 TPM2_HANDLE pcr;
1957 TPM2B_DIGEST value;
1958 } pcrs[TPM2_MAX_PCRS];
1959 size_t i, pcr, i_evt, hash_size, n_pcrs = 0, n_events = 0;
1960
1961 json_object *jso;
1962 IFAPI_EVENT event;
1963
1964 const TPML_PCR_SELECTION *pcr_selection;
1965 TPMI_ALG_HASH pcr_digest_hash_alg;
1966
1967 /* Get some data from the quote info for easier access */
1968 pcr_selection = &quote_info->attest.attested.quote.pcrSelect;
1969 pcr_digest->size = quote_info->attest.attested.quote.pcrDigest.size;
1970
1971 switch (quote_info->sig_scheme.scheme) {
1972 case TPM2_ALG_RSAPSS:
1973 pcr_digest_hash_alg = quote_info->sig_scheme.details.rsapss.hashAlg;
1974 break;
1975 case TPM2_ALG_RSASSA:
1976 pcr_digest_hash_alg = quote_info->sig_scheme.details.rsassa.hashAlg;
1977 break;
1978 case TPM2_ALG_ECDSA:
1979 pcr_digest_hash_alg = quote_info->sig_scheme.details.ecdsa.hashAlg;
1980 break;
1981 default:
1982 LOG_ERROR("Unknown sig scheme");
1983 return TSS2_FAPI_RC_BAD_VALUE;
1984 }
1985
1986 /* Initialize used pcrs */
1987 for (i = 0; i < pcr_selection->count; i++) {
1988 for (pcr = 0; pcr < TPM2_MAX_PCRS; pcr++) {
1989 uint8_t byte_idx = pcr / 8;
1990 uint8_t flag = 1 << (pcr % 8);
1991 if (flag & pcr_selection->pcrSelections[i].pcrSelect[byte_idx]) {
1992 hash_size = ifapi_hash_get_digest_size(pcr_selection->pcrSelections[i].hash);
1993 pcrs[n_pcrs].pcr = pcr;
1994 pcrs[n_pcrs].bank = pcr_selection->pcrSelections[i].hash;
1995 pcrs[n_pcrs].value.size = hash_size;
1996 memset(&pcrs[n_pcrs].value.buffer[0], 0, hash_size);
1997 n_pcrs += 1;
1998 }
1999 }
2000 }
2001
2002 /* Compute pcr values based on event list */
2003 if (jso_event_list) {
2004 n_events = json_object_array_length(jso_event_list);
2005 for (i_evt = 0; i_evt < n_events; i_evt++) {
2006 jso = json_object_array_get_idx(jso_event_list, i_evt);
2007 r = ifapi_json_IFAPI_EVENT_deserialize(jso, &event);
2008 goto_if_error(r, "Error serialize policy", error_cleanup);
2009
2010 for (i = 0; i < n_pcrs; i++) {
2011 r = ifapi_extend_vpcr(&pcrs[i].value, pcrs[i].bank, &event);
2012 goto_if_error2(r, "Extending vpcr %"PRIu32, error_cleanup, pcrs[i].pcr);
2013 }
2014 }
2015 }
2016
2017 /* Compute digest for the used pcrs */
2018 r = ifapi_crypto_hash_start(&cryptoContext, pcr_digest_hash_alg);
2019 return_if_error(r, "crypto hash start");
2020
2021 for (i = 0; i < n_pcrs; i++) {
2022 HASH_UPDATE_BUFFER(cryptoContext, &pcrs[i].value.buffer, pcrs[i].value.size,
2023 r, error_cleanup);
2024 }
2025 r = ifapi_crypto_hash_finish(&cryptoContext,
2026 (uint8_t *) &pcr_digest->buffer[0],
2027 &hash_size);
2028 return_if_error(r, "crypto hash finish");
2029 pcr_digest->size = hash_size;
2030
2031 /* Compare the digest from the event list with the digest from the attest */
2032 if (memcmp(&pcr_digest->buffer[0], &quote_info->attest.attested.quote.pcrDigest.buffer[0],
2033 pcr_digest->size) != 0) {
2034 goto_error(r, TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED,
2035 "The digest computed from event list does not match the attest.",
2036 error_cleanup);
2037 }
2038
2039 error_cleanup:
2040 if (cryptoContext)
2041 ifapi_crypto_hash_abort(&cryptoContext);
2042 ifapi_cleanup_event(&event);
2043 return r;
2044 }
2045
2046 /** Check whether profile PCR capabilities are a subset of TPM PCR capabilities.
2047 *
2048 * It has to be checked that every hash alg from the profile is available and
2049 * whether the selected PCRs are available.
2050 * @param[in] pcr_profile The pcr profile to use as basis for the selection.
2051 * @param[in] pcr_capablity The PCR capabilities available for TPM.
2052 * @retval TSS2_RC_SUCCESSS if the conversion was successful.
2053 * @retval TSS2_FAPI_RC_BAD_VALUE if profile is not subset of capabilities.
2054 */
2055 TSS2_RC
2056 ifapi_check_profile_pcr_selection(
2057 const TPML_PCR_SELECTION *pcr_profile,
2058 const TPML_PCR_SELECTION *pcr_capablity)
2059 {
2060 size_t i, j, k;
2061
2062 for (i = 0; i < pcr_profile->count; i++) {
2063 bool hash_found = false;
2064 for (j = 0; j < pcr_capablity->count; j++) {
2065 if (pcr_capablity->pcrSelections[j].hash ==
2066 pcr_profile->pcrSelections[i].hash) {
2067 /* Hash algorithm found, check PCRs */
2068 hash_found = true;
2069 if (pcr_profile->pcrSelections[i].sizeofSelect >
2070 pcr_capablity->pcrSelections[j].sizeofSelect) {
2071 return_error(TSS2_FAPI_RC_BAD_VALUE, "Invalid size of PCR select.");
2072 }
2073
2074 for (k = 0;
2075 k < pcr_profile->pcrSelections[i].sizeofSelect;
2076 k++) {
2077 /* Check whether all selected PCRs are available */
2078 if ((pcr_profile->pcrSelections[i].pcrSelect[k] &
2079 pcr_capablity->pcrSelections[j].pcrSelect[k])
2080 != pcr_profile->pcrSelections[i].pcrSelect[k]) {
2081 return_error(TSS2_FAPI_RC_BAD_VALUE, "Invalid PCR selection.");
2082
2083 }
2084 }
2085 }
2086 }
2087 if (!hash_found) {
2088 return_error(TSS2_FAPI_RC_BAD_VALUE,
2089 "Hash alg for PCR selection not available.");
2090 }
2091 }
2092 return TSS2_RC_SUCCESS;
2093 }
2094
2095 /** Reduce a PCR selection to a single pcr.
2096 *
2097 * This includes two steps: clearing all bits but the selected and clearing empty hashalg lines.
2098 *
2099 * @param[in,out] pcr_selection The pcr selection to be filtered.
2100 * @param[in] pcr_index The only PCR to remain selected.
2101 * @param[in] pcr_count The size of the pcr list.
2102 *
2103 * @retval TSS2_RC_SUCCESS if the filtering was successful.
2104 * @retval TSS2_FAPI_RC_BAD_VALUE if no pcr remain selected or the pcr selection is malformed.
2105 */
2106 TSS2_RC
2107 ifapi_filter_pcr_selection_by_index(
2108 TPML_PCR_SELECTION *pcr_selection,
2109 const TPM2_HANDLE *pcr_index,
2110 size_t pcr_count)
2111 {
2112 UINT32 bank, j;
2113 UINT16 select;
2114 size_t i;
2115 UINT8 selection[] = { 0, 0, 0, 0 };
2116
2117 for (i = 0; i < pcr_count; i++) {
2118 selection[0] |= (1 << pcr_index[i]) % 256;
2119 selection[1] |= (1 << (pcr_index[i] - 8)) % 256;
2120 selection[2] |= (1 << (pcr_index[i] - 16)) % 256;
2121 selection[3] |= (1 << (pcr_index[i] - 24)) % 256;
2122 };
2123
2124 /* Remove unselected PCRs */
2125 for (bank = 0; bank < pcr_selection->count; bank++) {
2126 if (pcr_selection->pcrSelections[bank].sizeofSelect > 4) {
2127 LOG_ERROR("pcrSelection's sizeofSelect exceeds allowed value of 4, is %"PRIu16,
2128 pcr_selection->pcrSelections[bank].sizeofSelect);
2129 return TSS2_FAPI_RC_BAD_VALUE;
2130 }
2131 for (select = 0; select < pcr_selection->pcrSelections[bank].sizeofSelect; select++) {
2132 pcr_selection->pcrSelections[bank].pcrSelect[select] &= selection[select];
2133 }
2134 }
2135
2136 /* Remove empty banks */
2137 for (bank = 0; bank < pcr_selection->count; ) {
2138 for (select = 0; select < pcr_selection->pcrSelections[bank].sizeofSelect; select++) {
2139 if (pcr_selection->pcrSelections[bank].pcrSelect[select])
2140 break;
2141 }
2142 if (select < pcr_selection->pcrSelections[bank].sizeofSelect) {
2143 /* Bank contains selections */
2144 bank ++;
2145 continue;
2146 }
2147
2148 /* Bank contains no selections, move all other banks one up */
2149 pcr_selection->count -= 1;
2150 for (j = bank; j < pcr_selection->count; j++) {
2151 pcr_selection->pcrSelections[j] = pcr_selection->pcrSelections[j+1];
2152 }
2153 }
2154
2155 if (pcr_selection->count == 0) {
2156 LOGBLOB_WARNING((void*)pcr_index, pcr_count * sizeof(*pcr_index),
2157 "pcr selection is empty after filtering for pcrlist");
2158 return TSS2_FAPI_RC_BAD_VALUE;
2159 }
2160 return TSS2_RC_SUCCESS;
2161 }
2162
2163 /** Compute PCR selection and a PCR digest for a PCR value list.
2164 *
2165 * @param[in] pcrs The list of PCR values.
2166 * @param[out] pcr_selection The selection computed based on the
2167 * list of PCR values.
2168 * @param[in] hash_alg The hash algorithm which is used for the policy computation.
2169 * @param[out] pcr_digest The computed PCR digest corresponding to the passed
2170 * PCR value list.
2171 *
2172 * @retval TSS2_RC_SUCCESS if the PCR selection and the PCR digest could be computed..
2173 * @retval TSS2_FAPI_RC_BAD_VALUE: If inappropriate values are detected in the
2174 * input data.
2175 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2176 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2177 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
2178 */
2179 TSS2_RC
2180 ifapi_compute_policy_digest(
2181 TPML_PCRVALUES *pcrs,
2182 TPML_PCR_SELECTION *pcr_selection,
2183 TPMI_ALG_HASH hash_alg,
2184 TPM2B_DIGEST *pcr_digest)
2185 {
2186 TSS2_RC r = TSS2_RC_SUCCESS;
2187 size_t i, j;
2188 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
2189 size_t hash_size;
2190 UINT32 pcr;
2191 UINT32 max_pcr = 0;
2192
2193 memset(pcr_selection, 0, sizeof(TPML_PCR_SELECTION));
2194
2195 /* Compute PCR selection */
2196 pcr_selection->count = 0;
2197 for (i = 0; i < pcrs->count; i++) {
2198 for (j = 0; j < pcr_selection->count; j++) {
2199 if (pcrs->pcrs[i].hashAlg ==
2200 pcr_selection->pcrSelections[j].hash) {
2201 break;
2202 }
2203 }
2204 if (j == pcr_selection->count) {
2205 /* New hash alg */
2206 pcr_selection->count += 1;
2207 if (pcr_selection->count > TPM2_NUM_PCR_BANKS) {
2208 return_error(TSS2_FAPI_RC_BAD_VALUE,
2209 "More hash algs than banks.");
2210 }
2211 pcr_selection->pcrSelections[j].hash =
2212 pcrs->pcrs[i].hashAlg;
2213 }
2214 UINT32 pcrIndex = pcrs->pcrs[i].pcr;
2215 if (pcrIndex + 1 > max_pcr)
2216 max_pcr = pcrIndex + 1;
2217 pcr_selection->pcrSelections[j].pcrSelect[pcrIndex / 8] |=
2218 1 << pcrIndex % 8;
2219 if ((pcrIndex / 8) + 1 > pcr_selection->pcrSelections[j].sizeofSelect)
2220 pcr_selection->pcrSelections[j].sizeofSelect = (pcrIndex / 8) + 1;
2221 }
2222 /* Compute digest for current pcr selection */
2223 r = ifapi_crypto_hash_start(&cryptoContext, hash_alg);
2224 return_if_error(r, "crypto hash start");
2225
2226 if (!(pcr_digest->size = ifapi_hash_get_digest_size(hash_alg))) {
2227 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
2228 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
2229 hash_alg);
2230 }
2231
2232 for (i = 0; i < pcr_selection->count; i++) {
2233 TPMS_PCR_SELECTION selection = pcr_selection->pcrSelections[i];
2234 TPMI_ALG_HASH hashAlg = selection.hash;
2235 if (!(hash_size = ifapi_hash_get_digest_size(hashAlg))) {
2236 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
2237 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
2238 hashAlg);
2239 }
2240 for (pcr = 0; pcr < max_pcr; pcr++) {
2241 if ((selection.pcrSelect[pcr / 8]) & (1 << (pcr % 8))) {
2242 /* pcr selected */
2243 for (j = 0; j < pcrs->count; j++) {
2244 if (pcrs->pcrs[j].pcr == pcr) {
2245 r = ifapi_crypto_hash_update(cryptoContext,
2246 (const uint8_t *)&pcrs->
2247 pcrs[j].digest,
2248 hash_size);
2249 goto_if_error(r, "crypto hash update", cleanup);
2250 }
2251 }
2252 }
2253 }
2254 }
2255 r = ifapi_crypto_hash_finish(&cryptoContext,
2256 (uint8_t *) & pcr_digest->buffer[0],
2257 &hash_size);
2258 cleanup:
2259 if (cryptoContext)
2260 ifapi_crypto_hash_abort(&cryptoContext);
2261 return r;
2262 }
2263
2264 /** Compare two public keys.
2265 *
2266 * @param[in] key1 The first key.
2267 * @param[in] key2 The second key.
2268 * @retval true if equal false if not.
2269 */
2270 bool
2271 ifapi_cmp_public_key(
2272 TPM2B_PUBLIC *key1,
2273 TPM2B_PUBLIC *key2)
2274 {
2275 if (key1->publicArea.type != key2->publicArea.type)
2276 return false;
2277 switch (key1->publicArea.type) {
2278 case TPM2_ALG_RSA:
2279 if (key1->publicArea.unique.rsa.size != key2->publicArea.unique.rsa.size) {
2280 return false;
2281 }
2282 LOGBLOB_TRACE(&key1->publicArea.unique.rsa.buffer[0],
2283 key1->publicArea.unique.rsa.size, "Key 1");
2284 LOGBLOB_TRACE(&key2->publicArea.unique.rsa.buffer[0],
2285 key2->publicArea.unique.rsa.size, "Key 2");
2286 if (memcmp(&key1->publicArea.unique.rsa.buffer[0],
2287 &key2->publicArea.unique.rsa.buffer[0],
2288 key1->publicArea.unique.rsa.size) == 0)
2289 return true;
2290 else
2291 return false;
2292 break;
2293 case TPM2_ALG_ECC:
2294 if (key1->publicArea.unique.ecc.x.size != key2->publicArea.unique.ecc.x.size) {
2295 return false;
2296 }
2297 LOGBLOB_TRACE(&key1->publicArea.unique.ecc.x.buffer[0],
2298 key1->publicArea.unique.ecc.x.size, "Key 1 x");
2299 LOGBLOB_TRACE(&key2->publicArea.unique.ecc.x.buffer[0],
2300 key2->publicArea.unique.ecc.x.size, "Key 2 x");
2301 if (memcmp(&key1->publicArea.unique.ecc.x.buffer[0],
2302 &key2->publicArea.unique.ecc.x.buffer[0],
2303 key1->publicArea.unique.ecc.x.size) != 0)
2304 return false;
2305 if (key1->publicArea.unique.ecc.y.size != key2->publicArea.unique.ecc.y.size) {
2306 return false;
2307 }
2308 LOGBLOB_TRACE(&key1->publicArea.unique.ecc.y.buffer[0],
2309 key1->publicArea.unique.ecc.y.size, "Key 1 x");
2310 LOGBLOB_TRACE(&key2->publicArea.unique.ecc.y.buffer[0],
2311 key2->publicArea.unique.ecc.y.size, "Key 2 x");
2312 if (memcmp(&key1->publicArea.unique.ecc.y.buffer[0],
2313 &key2->publicArea.unique.ecc.y.buffer[0],
2314 key1->publicArea.unique.ecc.y.size) != 0)
2315 return false;
2316 else
2317 return true;
2318 break;
2319
2320 default:
2321 return false;
2322 }
2323 }
2324
2325 struct CurlBufferStruct {
2326 unsigned char *buffer;
2327 size_t size;
2328 };
2329
2330 /** Callback for copying received curl data to a buffer.
2331 *
2332 * The buffer will be reallocated according to the size of retrieved data.
2333 *
2334 * @param[in] contents The retrieved content.
2335 * @param[in] size the block size in the content.
2336 * @param[in] nmemb The number of blocks.
2337 * @retval realsize The byte size of the data.
2338 */
2339 static size_t
2340 write_curl_buffer_cb(void *contents, size_t size, size_t nmemb, void *userp)
2341 {
2342 size_t realsize = size * nmemb;
2343 struct CurlBufferStruct *curl_buf = (struct CurlBufferStruct *)userp;
2344
2345 unsigned char *tmp_ptr = realloc(curl_buf->buffer, curl_buf->size + realsize + 1);
2346 if (tmp_ptr == NULL) {
2347 LOG_ERROR("Can't allocate memory in CURL callback.");
2348 return 0;
2349 }
2350 curl_buf->buffer = tmp_ptr;
2351 memcpy(&(curl_buf->buffer[curl_buf->size]), contents, realsize);
2352 curl_buf->size += realsize;
2353 curl_buf->buffer[curl_buf->size] = 0;
2354
2355 return realsize;
2356 }
2357
2358 /** Get byte buffer from file system or web via curl.
2359 *
2360 * @param[in] url The url of the resource.
2361 * @param[out] buffer The buffer retrieved via the url.
2362 * @param[out] buffer_size The size of the retrieved object.
2363 *
2364 * @retval 0 if buffer could be retrieved.
2365 * @retval -1 if an error did occur
2366 */
2367 int
2368 ifapi_get_curl_buffer(unsigned char * url, unsigned char ** buffer,
2369 size_t *buffer_size) {
2370 int ret = -1;
2371 struct CurlBufferStruct curl_buffer = { .size = 0, .buffer = NULL };
2372
2373 CURLcode rc = curl_global_init(CURL_GLOBAL_DEFAULT);
2374 if (rc != CURLE_OK) {
2375 LOG_ERROR("curl_global_init failed: %s", curl_easy_strerror(rc));
2376 goto out_memory;
2377 }
2378
2379 CURL *curl = curl_easy_init();
2380 if (!curl) {
2381 LOG_ERROR("curl_easy_init failed");
2382 goto out_global_cleanup;
2383 }
2384
2385 rc = curl_easy_setopt(curl, CURLOPT_URL, url);
2386 if (rc != CURLE_OK) {
2387 LOG_ERROR("curl_easy_setopt for CURLOPT_URL failed: %s",
2388 curl_easy_strerror(rc));
2389 goto out_easy_cleanup;
2390 }
2391
2392 rc = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
2393 write_curl_buffer_cb);
2394 if (rc != CURLE_OK) {
2395 LOG_ERROR("curl_easy_setopt for CURLOPT_URL failed: %s",
2396 curl_easy_strerror(rc));
2397 goto out_easy_cleanup;
2398 }
2399
2400 rc = curl_easy_setopt(curl, CURLOPT_WRITEDATA,
2401 (void *)&curl_buffer);
2402 if (rc != CURLE_OK) {
2403 LOG_ERROR("curl_easy_setopt for CURLOPT_URL failed: %s",
2404 curl_easy_strerror(rc));
2405 goto out_easy_cleanup;
2406 }
2407
2408 if (LOGMODULE_status == LOGLEVEL_TRACE) {
2409 if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L)) {
2410 LOG_WARNING("Curl easy setopt verbose failed");
2411 }
2412 }
2413
2414 rc = curl_easy_perform(curl);
2415 if (rc != CURLE_OK) {
2416 LOG_ERROR("curl_easy_perform() failed: %s", curl_easy_strerror(rc));
2417 goto out_easy_cleanup;
2418 }
2419
2420 *buffer = curl_buffer.buffer;
2421 *buffer_size = curl_buffer.size;
2422
2423 ret = 0;
2424
2425 out_easy_cleanup:
2426 if (ret != 0)
2427 free(curl_buffer.buffer);
2428 curl_easy_cleanup(curl);
2429 out_global_cleanup:
2430 curl_global_cleanup();
2431 out_memory:
2432 return ret;
2433 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef IFAPI_HELPERS_H
6 #define IFAPI_HELPERS_H
7
8 #include <stdint.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <json-c/json.h>
13 #include <json-c/json_util.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18
19 TSS2_RC
20 ifapi_create_dirs(const char *supdir, const char *path);
21
22 TSS2_RC
23 ifapi_set_key_flags(const char *type, bool policy, IFAPI_KEY_TEMPLATE *template);
24
25 TSS2_RC
26 ifapi_set_nv_flags(const char *type, IFAPI_NV_TEMPLATE *template,
27 const char *policy);
28
29 bool
30 ifapi_path_type_p(const char *path, const char *type);
31
32 ESYS_TR
33 ifapi_get_hierary_handle(const char *path);
34
35 bool
36 ifapi_hierarchy_path_p(const char *path);
37
38 bool
39 ifapi_TPMT_PUBLIC_cmp(TPMT_PUBLIC *in1, TPMT_PUBLIC *in2);
40
41 void
42 ifapi_init_hierarchy_object(
43 IFAPI_OBJECT *hierarchy,
44 ESYS_TR esys_handle);
45
46 char *
47 get_description(IFAPI_OBJECT *object);
48
49 size_t
50 ifapi_path_length(NODE_STR_T *node);
51
52 void
53 ifapi_free_object_list(NODE_OBJECT_T *node);
54
55 void
56 ifapi_free_node_list(NODE_OBJECT_T *node);
57
58 TSS2_RC
59 ifapi_path_string(char **dest, const char *supdir, NODE_STR_T *node, char *name);
60
61 TSS2_RC
62 ifapi_path_string_n(
63 char **dest,
64 const char *supdir,
65 NODE_STR_T *node,
66 char *name,
67 size_t n);
68
69 TSS2_RC
70 ifapi_asprintf(char **str, const char *fmt, ...);
71
72 NODE_STR_T *
73 split_string(const char *string, char *delimiter);
74
75 NODE_STR_T *
76 init_string_list(const char *string);
77
78 bool
79 add_string_to_list(NODE_STR_T *str_list, char *string);
80
81 void
82 free_string_list(NODE_STR_T *node);
83
84 void
85 ifapi_cleanup_policy(
86 TPMS_POLICY *policy);
87
88 TPMS_POLICY *
89 ifapi_copy_policy(
90 const TPMS_POLICY *from_policy);
91
92 TSS2_RC
93 ifapi_get_name(
94 TPMT_PUBLIC *publicInfo,
95 TPM2B_NAME *name);
96
97 TSS2_RC
98 ifapi_nv_get_name(
99 TPM2B_NV_PUBLIC *publicInfo,
100 TPM2B_NAME *name);
101
102 TSS2_RC
103 ifapi_object_cmp_name(
104 IFAPI_OBJECT *object,
105 void *name,
106 bool *equal);
107
108 TSS2_RC
109 ifapi_object_cmp_nv_public(
110 IFAPI_OBJECT *object,
111 void *nv_public,
112 bool *equal);
113
114 TSS2_RC
115 ifapi_tpm_to_fapi_signature(
116 IFAPI_OBJECT *sig_key_object,
117 TPMT_SIGNATURE *tpm_signature,
118 uint8_t **signature,
119 size_t *signatureSize);
120
121 TSS2_RC
122 ifapi_compute_quote_info(
123 IFAPI_OBJECT *sig_key_object,
124 TPM2B_ATTEST *tpm_quoted,
125 char **quoteInfo);
126
127 TSS2_RC
128 ifapi_get_quote_info(
129 char const *quoteInfo,
130 TPM2B_ATTEST *tpm_quoted,
131 FAPI_QUOTE_INFO *fapi_quote_ingo);
132
133 TSS2_RC
134 push_object_to_list(void *object, NODE_OBJECT_T **object_list);
135
136 TSS2_RC
137 append_object_to_list(void *object, NODE_OBJECT_T **object_list);
138
139 bool
140 object_with_auth(IFAPI_OBJECT *object);
141
142 TSS2_RC
143 ifapi_get_nv_start_index(const char *path, TPM2_HANDLE *start_nv_index);
144
145 TSS2_RC
146 ifapi_check_profile_pcr_selection(
147 const TPML_PCR_SELECTION *pcr_profile,
148 const TPML_PCR_SELECTION *pcr_capablity);
149
150 TSS2_RC
151 ifapi_filter_pcr_selection_by_index(
152 TPML_PCR_SELECTION *pcr_selection,
153 const TPM2_HANDLE *pcr_index,
154 size_t pcr_count);
155
156 TSS2_RC ifapi_calculate_pcr_digest(
157 json_object *jso_event_list,
158 const FAPI_QUOTE_INFO *quote_info,
159 TPM2B_DIGEST *pcr_digest);
160
161 TSS2_RC
162 ifapi_compute_policy_digest(
163 TPML_PCRVALUES *pcrs,
164 TPML_PCR_SELECTION *pcr_selection,
165 TPMI_ALG_HASH hash_alg,
166 TPM2B_DIGEST *pcr_digest);
167
168 bool
169 ifapi_cmp_public_key(
170 TPM2B_PUBLIC *key1,
171 TPM2B_PUBLIC *key2);
172
173 int
174 ifapi_get_curl_buffer(
175 unsigned char * url,
176 unsigned char ** buffer,
177 size_t *cert_size);
178
179 #endif /* IFAPI_HELPERS_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <poll.h>
16 #include <errno.h>
17 #include <sys/types.h>
18 #include <dirent.h>
19 /* Need for some libc-versions */
20 #ifndef __FreeBSD__
21 #include <malloc.h>
22 #endif
23
24 #include "tss2_common.h"
25 #include "ifapi_io.h"
26 #include "ifapi_helpers.h"
27 #include "ifapi_macros.h"
28 #define LOGMODULE fapi
29 #include "util/log.h"
30 #include "util/aux_util.h"
31
32 /** Start reading a file's complete content into memory in an asynchronous way.
33 *
34 * @param[in,out] io The input/output context being used for file I/O.
35 * @param[in] filename The name of the file to be read into memory.
36 * @retval TSS2_RC_SUCCESS: if the function call was a success.
37 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
38 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
39 */
40 TSS2_RC
41 ifapi_io_read_async(
42 struct IFAPI_IO *io,
43 const char *filename)
44 {
45 if (io->char_rbuffer) {
46 LOG_ERROR("rbuffer still in use; maybe use of old API.");
47 return TSS2_FAPI_RC_IO_ERROR;
48 }
49
50 io->stream = fopen(filename, "rt");
51 if (io->stream == NULL) {
52 LOG_ERROR("File \"%s\" not found.", filename);
53 return TSS2_FAPI_RC_IO_ERROR;
54 }
55 /* Locking the file. Lock will be release upon close */
56 if (lockf(fileno(io->stream), F_TLOCK, 0) == -1 && errno == EAGAIN) {
57 LOG_ERROR("File %s currently locked.", filename);
58 fclose(io->stream);
59 return TSS2_FAPI_RC_IO_ERROR;
60 }
61
62 fseek(io->stream, 0L, SEEK_END);
63 long length = ftell(io->stream);
64 fclose(io->stream);
65
66 io->stream = fopen(filename, "rt");
67 io->char_rbuffer = malloc (length + 1);
68 if (io->char_rbuffer == NULL) {
69 fclose(io->stream);
70 io->stream = NULL;
71 LOG_ERROR("Memory could not be allocated. %li bytes requested", length + 1);
72 return TSS2_FAPI_RC_MEMORY;
73 }
74
75 int rc, flags = fcntl(fileno(io->stream), F_GETFL, 0);
76 rc = fcntl(fileno(io->stream), F_SETFL, flags | O_NONBLOCK);
77 if (rc < 0) {
78 LOG_ERROR("fcntl failed with %d", errno);
79 return TSS2_FAPI_RC_IO_ERROR;
80 }
81
82 io->buffer_length = length;
83 io->buffer_idx = 0;
84 io->char_rbuffer[length] = '\0';
85
86 return TSS2_RC_SUCCESS;
87 }
88
89 /** Finish reading a file's complete content into memory in an asynchronous way.
90 *
91 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
92 *
93 * @param[in,out] io The input/output context being used for file I/O.
94 * @param[out] buffer The data that was read from file. (callee-allocated; use free())
95 * @param[out] length The length of the data that was read from file.
96 * @retval TSS2_RC_SUCCESS: if the function call was a success.
97 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
98 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
99 * Call this function again later.
100 */
101 TSS2_RC
102 ifapi_io_read_finish(
103 struct IFAPI_IO *io,
104 uint8_t **buffer,
105 size_t *length)
106 {
107 io->pollevents = POLLIN;
108 if (_ifapi_io_retry-- > 0)
109 return TSS2_FAPI_RC_TRY_AGAIN;
110 else
111 _ifapi_io_retry = _IFAPI_IO_RETRIES;
112
113 ssize_t ret = read(fileno(io->stream),
114 &io->char_rbuffer[io->buffer_idx],
115 io->buffer_length - io->buffer_idx);
116 if (ret < 0 && (errno == EINTR || errno == EAGAIN))
117 return TSS2_FAPI_RC_TRY_AGAIN;
118
119 if (ret < 0) {
120 LOG_ERROR("Error reading from file: %i.", errno);
121 fclose(io->stream);
122 io->pollevents = 0;
123 SAFE_FREE(io->char_rbuffer);
124 return TSS2_FAPI_RC_IO_ERROR;
125 }
126
127 io->pollevents = 0;
128 io->buffer_idx += ret;
129 if (io->buffer_idx < io->buffer_length)
130 return TSS2_FAPI_RC_TRY_AGAIN;
131
132 fclose(io->stream);
133
134 if (!buffer) {
135 LOG_WARNING("The old file read API is still being used");
136 return TSS2_RC_SUCCESS;
137 }
138 *buffer = (uint8_t *)io->char_rbuffer;
139 io->char_rbuffer = NULL;
140
141 if (length)
142 *length = io->buffer_length;
143
144 return TSS2_RC_SUCCESS;
145 }
146
147 /** Start writing a buffer into a file in an asynchronous way.
148 *
149 * @param[in,out] io The input/output context being used for file I/O.
150 * @param[in] filename The name of the file to be read into memory.
151 * @param[in] buffer The buffer to be written.
152 * @param[in] length The number of bytes to be written.
153 * @retval TSS2_RC_SUCCESS: if the function call was a success.
154 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
155 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
156 */
157 TSS2_RC
158 ifapi_io_write_async(
159 struct IFAPI_IO *io,
160 const char *filename,
161 const uint8_t *buffer,
162 size_t length)
163 {
164 if (io->char_rbuffer) {
165 LOG_ERROR("rbuffer still in use; maybe use of old API.");
166 return TSS2_FAPI_RC_IO_ERROR;
167 }
168
169 io->buffer_length = length;
170 io->buffer_idx = 0;
171 io->char_rbuffer = malloc(length);
172 if (io->char_rbuffer == NULL) {
173 LOG_ERROR("Memory could not be allocated. %zi bytes requested", length);
174 return TSS2_FAPI_RC_MEMORY;
175 }
176 memcpy(io->char_rbuffer, buffer, length);
177
178 io->stream = fopen(filename, "wt");
179 if (io->stream == NULL) {
180 SAFE_FREE(io->char_rbuffer);
181 LOG_ERROR("Could not open file \"%s\" for writing.", filename);
182 return TSS2_FAPI_RC_IO_ERROR;
183 }
184 /* Locking the file. Lock will be release upon close */
185 if (lockf(fileno(io->stream), F_TLOCK, 0) == -1 && errno == EAGAIN) {
186 LOG_ERROR("File %s currently locked.", filename);
187 fclose(io->stream);
188 return TSS2_FAPI_RC_IO_ERROR;
189 }
190
191 /* Use non blocking IO, so asynchronous write will be needed */
192 int rc, flags = fcntl(fileno(io->stream), F_GETFL, 0);
193 rc = fcntl(fileno(io->stream), F_SETFL, flags | O_NONBLOCK);
194 if (rc < 0) {
195 LOG_ERROR("fcntl failed with %d", errno);
196 return TSS2_FAPI_RC_IO_ERROR;
197 }
198 return TSS2_RC_SUCCESS;
199 }
200
201 /** Finish writing a buffer into a file in an asynchronous way.
202 *
203 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
204 *
205 * @param[in,out] io The input/output context being used for file I/O.
206 * @retval TSS2_RC_SUCCESS: if the function call was a success.
207 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
208 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
209 * Call this function again later.
210 */
211 TSS2_RC
212 ifapi_io_write_finish(
213 struct IFAPI_IO *io)
214 {
215 io->pollevents = POLLOUT;
216 if (_ifapi_io_retry-- > 0)
217 return TSS2_FAPI_RC_TRY_AGAIN;
218 else
219 _ifapi_io_retry = _IFAPI_IO_RETRIES;
220
221 ssize_t ret = write(fileno(io->stream),
222 &io->char_rbuffer[io->buffer_idx],
223 io->buffer_length - io->buffer_idx);
224 if (ret < 0 && (errno == EINTR || errno == EAGAIN))
225 return TSS2_FAPI_RC_TRY_AGAIN;
226
227 if (ret < 0) {
228 LOG_ERROR("Error writing to file: %i.", errno);
229 fclose(io->stream);
230 io->pollevents = 0;
231 SAFE_FREE(io->char_rbuffer);
232 return TSS2_FAPI_RC_IO_ERROR;
233 }
234
235 io->pollevents = 0;
236 io->buffer_idx += ret;
237 if (io->buffer_idx < io->buffer_length)
238 return TSS2_FAPI_RC_TRY_AGAIN;
239
240 SAFE_FREE(io->char_rbuffer);
241 fclose(io->stream);
242
243 return TSS2_RC_SUCCESS;
244 }
245
246 /** Check whether a file is writeable.
247 *
248 * @param[in] file The name of the fileto be checked.
249 * @retval TSS2_RC_SUCCESS if the directories existed or were successfully created
250 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error occurred
251 */
252 TSS2_RC
253 ifapi_io_check_file_writeable(
254 const char *file)
255 {
256 /* Check access rights to file */
257 if (access(file, W_OK)) {
258 return_error2(TSS2_FAPI_RC_IO_ERROR, "File %s is not writeable.", file);
259 }
260 return TSS2_RC_SUCCESS;
261 }
262
263 /** Check for the existence of a directory and create it if it does not yet exist.
264 *
265 * @param[in] dirname The name of the directory to be checked / created
266 * @retval TSS2_RC_SUCCESS if the directories existed or were successfully created
267 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error occurred
268 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
269 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
270 * the function.
271 */
272 TSS2_RC
273 ifapi_io_check_create_dir(
274 const char *dirname)
275 {
276 TSS2_RC r;
277 struct stat fbuffer;
278
279 /* Check existence of dirname and try to create it otherwise */
280 if (stat(dirname, &fbuffer)) {
281 LOG_WARNING("Directory %s does not exist, creating", dirname);
282
283 r = ifapi_create_dirs("", dirname);
284 return_if_error2(r, "Directory %s can't be created.", dirname);
285
286 LOG_DEBUG("Created directory: %s", dirname);
287 }
288
289 /* Check access rights to dirname */
290 if (access(dirname, W_OK)) {
291 return_error2(TSS2_FAPI_RC_IO_ERROR, "Directory %s is not writeable.", dirname);
292 }
293
294 return TSS2_RC_SUCCESS;
295 }
296
297 /** Remove a file.
298 *
299 * @param[in] file The absolute path of the file to be removed.
300 * @retval TSS2_RC_SUCCESS If the file was successfully removed
301 * @retval TSS2_FAPI_RC_IO_ERROR If the file could not be removed.
302 */
303 TSS2_RC
304 ifapi_io_remove_file(const char *file)
305 {
306 if (remove(file) != 0) {
307 LOG_ERROR("File: %s can't be deleted.", file);
308 return TSS2_FAPI_RC_IO_ERROR;
309 }
310 return TSS2_RC_SUCCESS;
311 }
312
313 /** Remove a directory recursively; i.e. including its subdirectories.
314 *
315 * @param[in] dirname The directory to be removed
316 * @retval TSS2_RC_SUCCESS if the directories were successfully removed
317 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error occurred
318 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
319 */
320 TSS2_RC
321 ifapi_io_remove_directories(
322 const char *dirname)
323 {
324 DIR *dir;
325 struct dirent *entry;
326 TSS2_RC r;
327 char *path;
328
329 LOG_TRACE("Removing directory: %s", dirname);
330
331 if (!(dir = opendir(dirname))) {
332 return_error2(TSS2_FAPI_RC_IO_ERROR, "Could not open directory: %s",
333 dirname);
334 }
335
336 /* Iterating through the list of entries inside the directory. */
337 while ((entry = readdir(dir)) != NULL) {
338 LOG_TRACE("Deleting directory entry %s", entry->d_name);
339
340 /* Entries . and .. are obviously ignored */
341 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
342 continue;
343
344 /* If an entry is a directory then we call ourself recursively to remove those */
345 if (entry->d_type == DT_DIR) {
346 r = ifapi_asprintf(&path, "%s/%s", dirname, entry->d_name);
347 goto_if_error(r, "Out of memory", error_cleanup);
348
349 r = ifapi_io_remove_directories(path);
350 free(path);
351 goto_if_error(r, "remove directories.", error_cleanup);
352
353 continue;
354 }
355
356 /* If an entry is a file or symlink or anything else, we remove it */
357 r = ifapi_asprintf(&path, "%s/%s", dirname, entry->d_name);
358 goto_if_error(r, "Out of memory", error_cleanup);
359
360 LOG_WARNING("Found a file in directory; removing: %s", path);
361
362 if (remove(path) != 0) {
363 free(path);
364 closedir(dir);
365 return_error2(TSS2_FAPI_RC_IO_ERROR, "Removing file");
366 }
367
368 free(path);
369 }
370 closedir(dir);
371 LOG_TRACE("Removing target directory %s", dirname);
372
373 if (rmdir(dirname) != 0)
374 return_error2(TSS2_FAPI_RC_IO_ERROR, "Removing directory: %s", dirname);
375
376 LOG_TRACE("SUCCESS");
377 return TSS2_RC_SUCCESS;
378
379 error_cleanup:
380 closedir(dir);
381 return r;
382 }
383
384 /** Enumerate the list of files in a directory.
385 *
386 * Enumerage the regular files (no directories, symlinks etc) from a given directory.
387 *
388 * @param[in] dirname The directory to list files from.
389 * @param[out] files The list of file names.
390 * @param[out] numfiles The size of files.
391 * @retval TSS2_RC_SUCCESS if the directories were successfully removed
392 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error occurred
393 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
394 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
395 */
396 TSS2_RC
397 ifapi_io_dirfiles(
398 const char *dirname,
399 char ***files,
400 size_t *numfiles)
401 {
402 DIR *dir;
403 struct dirent *entry;
404 char **paths;
405 size_t numpaths = 0;
406 check_not_null(dirname);
407 check_not_null(files);
408 check_not_null(numfiles);
409
410 LOG_TRACE("Removing directory: %s", dirname);
411
412 paths = calloc(10, sizeof(*paths));
413 check_oom(paths);
414
415 if (!(dir = opendir(dirname))) {
416 free(paths);
417 return_error2(TSS2_FAPI_RC_IO_ERROR, "Could not open directory: %s",
418 dirname);
419 }
420
421 /* Iterating through the list of entries inside the directory. */
422 while ((entry = readdir(dir)) != NULL) {
423 LOG_TRACE("Looking at %s", entry->d_name);
424 if (entry->d_type != DT_REG)
425 continue;
426
427 if (numpaths % 10 == 9) {
428 #ifdef HAVE_REALLOCARRAY
429 paths = reallocarray(paths, numpaths + 10, sizeof(*paths));
430 #else /* HAVE_REALLOCARRAY */
431 paths = realloc(paths, (numpaths + 10) * sizeof(*paths));
432 #endif /* HAVE_REALLOCARRAY */
433 if (!paths)
434 closedir(dir);
435 check_oom(paths);
436 }
437
438 paths[numpaths] = strdup(entry->d_name);
439 if (!paths[numpaths])
440 goto error_oom;
441
442 LOG_TRACE("Added %s to the list at index %zi", paths[numpaths], numpaths);
443 numpaths += 1;
444 }
445 closedir(dir);
446
447 *files = paths;
448 *numfiles = numpaths;
449
450 return TSS2_RC_SUCCESS;
451
452 error_oom:
453 closedir(dir);
454 LOG_ERROR("Out of memory");
455 for (size_t i = 0; i < numpaths; i++)
456 free(paths[i]);
457 free(paths);
458 return TSS2_FAPI_RC_MEMORY;
459 }
460
461 /** Get a linked list of files in a directory and all sub directories.
462 *
463 * Enumerage the regular files (no directories, symlinks etc) from a given directory.
464 *
465 * @param[in] dir_name The directory to list files from.
466 * @param[out] list The linked list with the file names.
467 * @param[out] n The number of filesl
468 * @retval TSS2_RC_SUCCESS if the directories were successfully removed
469 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
470 */
471 static TSS2_RC
472 dirfiles_all(const char *dir_name, NODE_OBJECT_T **list, size_t *n)
473 {
474 DIR *dir;
475 struct dirent *entry;
476 TSS2_RC r;
477 char *path;
478 NODE_OBJECT_T *second;
479
480 if (!(dir = opendir(dir_name))) {
481 return TSS2_RC_SUCCESS;
482 }
483
484 /* Iterating through the list of entries inside the directory. */
485 while ((entry = readdir(dir)) != NULL) {
486 path = NULL;
487 if (entry->d_type == DT_DIR) {
488 /* Recursive call for sub directories */
489 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
490 continue;
491 r = ifapi_asprintf(&path, "%s/%s", dir_name, entry->d_name);
492 if (r)
493 closedir(dir);
494 return_if_error(r, "Out of memory");
495
496 LOG_TRACE("Directory: %s", path);
497 r = dirfiles_all(path, list, n);
498 SAFE_FREE(path);
499 if (r)
500 closedir(dir);
501 return_if_error(r, "get_entities");
502
503 } else {
504 r = ifapi_asprintf(&path, "%s/%s", dir_name, entry->d_name);
505 if (r)
506 closedir(dir);
507 return_if_error(r, "Out of memory");
508
509 NODE_OBJECT_T *file_obj = calloc(sizeof(NODE_OBJECT_T), 1);
510 if (!file_obj) {
511 LOG_ERROR("Out of memory.");
512 SAFE_FREE(path);
513 closedir(dir);
514 return TSS2_FAPI_RC_MEMORY;
515 }
516
517 *n += 1;
518 /* Add file name to linked list */
519 file_obj->object = strdup(path);
520 if (file_obj->object == NULL) {
521 LOG_ERROR("Out of memory.");
522 SAFE_FREE(file_obj);
523 SAFE_FREE(path);
524 closedir(dir);
525 return TSS2_FAPI_RC_MEMORY;
526 }
527 if (*list != NULL) {
528 second = *list;
529 file_obj->next = second;
530 }
531 *list = file_obj;
532 LOG_TRACE("File: %s", path);
533 SAFE_FREE(path);
534 }
535 }
536 closedir(dir);
537 return TSS2_RC_SUCCESS;
538 }
539
540
541 /** Recursive enumerate the list of files in a directory.
542 *
543 * Enumerage the regular files (no directories, symlinks etc) from a given directory.
544 *
545 * @param[in] searchPath The directory to list files from.
546 * @param[out] pathlist The list of file names.
547 * @param[out] numPaths The size of files.
548 * @retval TSS2_RC_SUCCESS if the directories were successfully removed
549 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error occurred
550 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
551 */
552 TSS2_RC
553 ifapi_io_dirfiles_all(
554 const char *searchPath,
555 char ***pathlist,
556 size_t *numPaths)
557 {
558 TSS2_RC r;
559 size_t n;
560 NODE_OBJECT_T *head;
561
562 *numPaths = 0;
563 char **pathlist2;
564
565 NODE_OBJECT_T *file_list = NULL;
566 r = dirfiles_all(searchPath, &file_list, numPaths);
567 goto_if_error(r, "get all sub files of directory", cleanup);
568
569 if (*numPaths > 0) {
570 size_t size_path_list = *numPaths * sizeof(char *);
571 pathlist2 = calloc(1, size_path_list);
572 goto_if_null2(pathlist2, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
573 cleanup);
574 n = *numPaths;
575
576 /* Move file names from list to array */
577 while (n > 0 && file_list) {
578 n -= 1;
579 pathlist2[n] = file_list->object;
580 head = file_list;
581 file_list = file_list->next;
582 SAFE_FREE(head);
583 }
584 *pathlist = pathlist2;
585 }
586 cleanup:
587 /* Free linked list with file names */
588 while (file_list) {
589 head = file_list;
590 file_list = file_list->next;
591 SAFE_FREE(head);
592 }
593 return r;
594 }
595
596 /** Determine whether a path exists.
597 *
598 * @param[in] path The absolute path of the file.
599 * @retval true The file exists.
600 * @retval false The file does not exist.
601 */
602 bool
603 ifapi_io_path_exists(const char *path)
604 {
605 struct stat fbuffer;
606
607 if (stat(path, &fbuffer) == 0)
608 return true;
609 else
610 return false;
611 }
612
613
614 /** Wait for file I/O to be ready.
615 *
616 * If FAPI state automata are in a file I/O state it will be waited for an
617 * event on a file descriptor.
618 *
619 * @param[in] io The input/output context being used for file I/O.
620 * @retval TSS2_RC_SUCCESS After the end of the wait.
621 * @retval TSS2_FAPI_RC_IO_ERROR if the poll function returns an error.
622 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
623 */
624 TSS2_RC
625 ifapi_io_poll(IFAPI_IO * io) {
626 int rc;
627 /* Check for NULL parameters */
628 check_not_null(io);
629
630 if (io->pollevents) {
631 struct pollfd fds;
632 fds.events = io->pollevents;
633 fds.fd = fileno(io->stream);
634 LOG_TRACE("Waiting for fd %i with event %i", fds.fd, fds.events);
635 rc = poll(&fds, 1, -1);
636 if (rc < 0) {
637 LOG_ERROR("Poll failed with %d", errno);
638 return TSS2_FAPI_RC_IO_ERROR;
639 }
640 }
641 return TSS2_RC_SUCCESS;
642 }
643
644 /** Get a list of poll handles.
645 *
646 * @param[in] io The input/output context being used for file I/O.
647 * @param[out] handles The array with the poll handles.
648 * @param[out] num_handles The number of poll handles.
649 * @retval TSS2_RC_SUCCESS on success.
650 * @retval TSS2_FAPI_RC_NO_HANDLE In no poll events are stored in IO context.
651 * @retval TSS2_FAPI_RC_MEMORY If the output data cannot be allocated.
652 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
653 */
654 TSS2_RC
655 ifapi_io_poll_handles(IFAPI_IO *io, FAPI_POLL_HANDLE **handles, size_t *num_handles) {
656 /* Check for NULL parameters */
657 check_not_null(io);
658 check_not_null(handles);
659 check_not_null(num_handles);
660
661 if (!io->pollevents) {
662 /* We're not spilling out error here, because this is called in the
663 functional path of Fapi_GetPollHandles(). */
664 LOG_DEBUG("No pollable operation in progress.");
665 return TSS2_FAPI_RC_NO_HANDLE;
666 }
667
668 *handles = calloc(1, sizeof(**handles));
669 check_oom(*handles);
670 (*handles)->events = io->pollevents;
671 (*handles)->fd = fileno(io->stream);
672 *num_handles = 1;
673
674 LOG_TRACE("Returning %zi poll handles for fd %i with event %i",
675 *num_handles, (*handles)->fd, (*handles)->events);
676
677 return TSS2_RC_SUCCESS;
678 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifndef IFAPI_IO_H
7 #define IFAPI_IO_H
8
9 #include <stdio.h>
10 #include <stdbool.h>
11 #include "tss2_common.h"
12 #include "tss2_fapi.h"
13
14 typedef struct IFAPI_IO {
15 FILE *stream;
16 short pollevents;
17 const char *char_buffer;
18 char *char_rbuffer;
19 size_t buffer_length;
20 size_t buffer_idx;
21 } IFAPI_IO;
22
23 #ifdef TEST_FAPI_ASYNC
24 #define _IFAPI_IO_RETRIES 1
25 #else /* TEST_FAPI_ASYNC */
26 #define _IFAPI_IO_RETRIES 0
27 #endif /* TEST_FAPI_ASYNC */
28
29 static int _ifapi_io_retry __attribute__((unused)) = _IFAPI_IO_RETRIES;
30
31 #define IFAPI_IO_STREAM context->io.stream
32 #define IFAPI_IO_BUFF context->io.char_buffer
33 #define IFAPI_IO_RBUFF context->io.char_rbuffer
34 #define IFAPI_IO_BUFFLEN context->io.buffer_length
35 #define IFAPI_IO_BUFFIDX context->io.buffer_idx
36
37 TSS2_RC
38 ifapi_io_read_async(
39 struct IFAPI_IO *io,
40 const char *filename);
41
42 TSS2_RC
43 ifapi_io_read_finish(
44 struct IFAPI_IO *io,
45 uint8_t **buffer,
46 size_t *length);
47
48 TSS2_RC
49 ifapi_io_write_async(
50 struct IFAPI_IO *io,
51 const char *filename,
52 const uint8_t *buffer,
53 size_t length);
54
55 TSS2_RC
56 ifapi_io_write_finish(
57 struct IFAPI_IO *io);
58
59 TSS2_RC
60 ifapi_io_check_file_writeable(
61 const char *file);
62
63 TSS2_RC
64 ifapi_io_check_create_dir(
65 const char *dirname);
66
67 TSS2_RC
68 ifapi_io_remove_file(
69 const char *file);
70
71 TSS2_RC
72 ifapi_io_remove_directories(
73 const char *dirname);
74
75 TSS2_RC
76 ifapi_io_dirfiles(
77 const char *dirname,
78 char ***files,
79 size_t *numfiles);
80
81 TSS2_RC
82 ifapi_io_dirfiles_all(
83 const char *searchPath,
84 char ***pathlist,
85 size_t *numPaths);
86
87 bool
88 ifapi_io_path_exists(const char *path);
89
90 TSS2_RC
91 ifapi_io_poll(IFAPI_IO * io);
92
93 TSS2_RC
94 ifapi_io_poll_handles(IFAPI_IO *io, FAPI_POLL_HANDLE **handles, size_t *num_handles);
95
96 #endif /* IFAPI_IO_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "tpm_json_deserialize.h"
14 #include "ifapi_json_deserialize.h"
15 #include "fapi_policy.h"
16 #include "ifapi_config.h"
17 #define LOGMODULE fapijson
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 static char *tss_const_prefixes[] = { "TPM2_ALG_", "TPM2_", "TPM_", "TPMA_", "POLICY", NULL };
22
23 /** Get the index of a sub string after a certain prefix.
24 *
25 * The prefixes from table tss_const_prefixes will be used for case
26 * insensitive comparison.
27 *
28 * param[in] token the token with a potential prefix.
29 * @retval the position of the sub string after the prefix.
30 * @retval 0 if no prefix is found.
31 */
32 static int
33 get_token_start_idx(const char *token)
34 {
35 int itoken = 0;
36 char *entry;
37 int i;
38
39 for (i = 0, entry = tss_const_prefixes[0]; entry != NULL;
40 i++, entry = tss_const_prefixes[i]) {
41 if (strncasecmp(token, entry, strlen(entry)) == 0) {
42 itoken += strlen(entry);
43 break;
44 }
45 }
46 return itoken;
47 }
48
49 /** Get number from a string.
50 *
51 * A string which represents a number or hex number (prefix 0x) is converted
52 * to an int64 number.
53 *
54 * param[in] token the string representing the number.
55 * param[out] num the converted number.
56 * @retval true if token represents a number
57 * @retval false if token does not represent a number.
58 */
59 static bool
60 get_number(const char *token, int64_t *num)
61 {
62 int itoken = 0;
63 int pos = 0;
64 if (strncmp(token, "0x", 2) == 0) {
65 itoken = 2;
66 sscanf(&token[itoken], "%"PRIx64"%n", num, &pos);
67 } else {
68 sscanf(&token[itoken], "%"PRId64"%n", num, &pos);
69 }
70 if ((size_t)pos == strlen(token) - itoken)
71 return true;
72 else
73 return false;
74 }
75
76 /** Deserialize a character string.
77 *
78 * @param[in] jso json string object.
79 * @param[out] out the pointer to the created string.
80 * @retval TSS2_RC_SUCCESS if the function call was a success.
81 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
82 */
83 TSS2_RC
84 ifapi_json_char_deserialize(
85 json_object *jso,
86 char **out)
87 {
88 *out = strdup(json_object_get_string(jso));
89 return_if_null(*out, "Out of memory.", TSS2_FAPI_RC_MEMORY);
90 return TSS2_RC_SUCCESS;
91 }
92
93 /** Deserialize a IFAPI_KEY json object.
94 *
95 * @param[in] jso the json object to be deserialized.
96 * @param[out] out the deserialzed binary object.
97 * @retval TSS2_RC_SUCCESS if the function call was a success.
98 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
99 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
100 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
101 */
102 TSS2_RC
103 ifapi_json_IFAPI_KEY_deserialize(json_object *jso, IFAPI_KEY *out)
104 {
105 json_object *jso2;
106 TSS2_RC r;
107 LOG_TRACE("call");
108 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
109
110
111 if (!ifapi_get_sub_object(jso, "persistent_handle", &jso2)) {
112 LOG_ERROR("Bad value");
113 return TSS2_FAPI_RC_BAD_VALUE;
114 }
115 r = ifapi_json_UINT32_deserialize(jso2, &out->persistent_handle);
116 return_if_error(r, "BAD VALUE");
117
118 if (ifapi_get_sub_object(jso, "with_auth", &jso2)) {
119 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->with_auth);
120 return_if_error(r, "BAD VALUE");
121
122 } else {
123 out->with_auth = TPM2_NO;
124 }
125
126 if (!ifapi_get_sub_object(jso, "public", &jso2)) {
127 LOG_ERROR("Bad value");
128 return TSS2_FAPI_RC_BAD_VALUE;
129 }
130 r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public);
131 return_if_error(r, "BAD VALUE");
132
133 if (!ifapi_get_sub_object(jso, "serialization", &jso2)) {
134 LOG_ERROR("Bad value");
135 return TSS2_FAPI_RC_BAD_VALUE;
136 }
137 r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->serialization);
138 return_if_error(r, "BAD VALUE");
139
140 if (!ifapi_get_sub_object(jso, "private", &jso2)) {
141 memset(&out->private, 0, sizeof(UINT8_ARY));
142 } else {
143 r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->private);
144 return_if_error(r, "BAD VALUE");
145 }
146
147 if (!ifapi_get_sub_object(jso, "appData", &jso2)) {
148 memset(&out->appData, 0, sizeof(UINT8_ARY));
149 } else {
150 r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->appData);
151 return_if_error(r, "BAD VALUE");
152 }
153
154 if (!ifapi_get_sub_object(jso, "policyInstance", &jso2)) {
155 LOG_ERROR("Bad value");
156 return TSS2_FAPI_RC_BAD_VALUE;
157 }
158 r = ifapi_json_char_deserialize(jso2, &out->policyInstance);
159 return_if_error(r, "BAD VALUE");
160
161 if (ifapi_get_sub_object(jso, "creationData", &jso2)) {
162 r = ifapi_json_TPM2B_CREATION_DATA_deserialize(jso2, &out->creationData);
163 return_if_error(r, "BAD VALUE");
164
165 } else {
166 memset(&out->creationData, 0, sizeof(TPM2B_CREATION_DATA));
167 }
168
169 if (ifapi_get_sub_object(jso, "creationTicket", &jso2)) {
170 r = ifapi_json_TPMT_TK_CREATION_deserialize(jso2, &out->creationTicket);
171 return_if_error(r, "BAD VALUE");
172
173 } else {
174 memset(&out->creationData, 0, sizeof(TPMT_TK_CREATION));
175 }
176 if (!ifapi_get_sub_object(jso, "description", &jso2)) {
177 LOG_ERROR("Bad value");
178 return TSS2_FAPI_RC_BAD_VALUE;
179 }
180 r = ifapi_json_char_deserialize(jso2, &out->description);
181 return_if_error(r, "BAD VALUE");
182
183 if (!ifapi_get_sub_object(jso, "certificate", &jso2)) {
184 LOG_ERROR("Bad value");
185 return TSS2_FAPI_RC_BAD_VALUE;
186 }
187 r = ifapi_json_char_deserialize(jso2, &out->certificate);
188 return_if_error(r, "BAD VALUE");
189
190 if (out->public.publicArea.type != TPM2_ALG_KEYEDHASH) {
191 /* Keyed hash objects to not need a signing scheme. */
192 if (!ifapi_get_sub_object(jso, "signing_scheme", &jso2)) {
193 LOG_ERROR("Bad value");
194 return TSS2_FAPI_RC_BAD_VALUE;
195 }
196 r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->signing_scheme);
197 return_if_error(r, "BAD VALUE");
198 }
199
200 if (!ifapi_get_sub_object(jso, "name", &jso2)) {
201 LOG_ERROR("Bad value");
202 return TSS2_FAPI_RC_BAD_VALUE;
203 }
204 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->name);
205 return_if_error(r, "BAD VALUE");
206 LOG_TRACE("true");
207 return TSS2_RC_SUCCESS;
208 }
209
210 /** Deserialize a IFAPI_EXT_PUB_KEY json object.
211 *
212 * @param[in] jso the json object to be deserialized.
213 * @param[out] out the deserialzed binary object.
214 * @retval TSS2_RC_SUCCESS if the function call was a success.
215 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
216 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
217 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
218 */
219 TSS2_RC
220 ifapi_json_IFAPI_EXT_PUB_KEY_deserialize(json_object *jso,
221 IFAPI_EXT_PUB_KEY *out)
222 {
223 json_object *jso2;
224 TSS2_RC r;
225 LOG_TRACE("call");
226 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
227
228
229 if (!ifapi_get_sub_object(jso, "pem_ext_public", &jso2)) {
230 LOG_ERROR("Bad value");
231 return TSS2_FAPI_RC_BAD_VALUE;
232 }
233 r = ifapi_json_char_deserialize(jso2, &out->pem_ext_public);
234 return_if_error(r, "BAD VALUE");
235
236 if (ifapi_get_sub_object(jso, "certificate", &jso2)) {
237 r = ifapi_json_char_deserialize(jso2, &out->certificate);
238 return_if_error(r, "BAD VALUE");
239 } else {
240 out->certificate = NULL;
241 }
242
243 if (ifapi_get_sub_object(jso, "public", &jso2)) {
244 r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public);
245 return_if_error(r, "BAD VALUE");
246
247 } else {
248 memset(&out->public, 0, sizeof(TPM2B_PUBLIC));
249 }
250 LOG_TRACE("true");
251 return TSS2_RC_SUCCESS;
252 }
253
254 /** Deserialize a IFAPI_NV json object.
255 *
256 * @param[in] jso the json object to be deserialized.
257 * @param[out] out the deserialzed binary object.
258 * @retval TSS2_RC_SUCCESS if the function call was a success.
259 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
260 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
261 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
262 */
263 TSS2_RC
264 ifapi_json_IFAPI_NV_deserialize(json_object *jso, IFAPI_NV *out)
265 {
266 json_object *jso2;
267 TSS2_RC r;
268 LOG_TRACE("call");
269 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
270
271 if (!ifapi_get_sub_object(jso, "appData", &jso2)) {
272 memset(&out->appData, 0, sizeof(UINT8_ARY));
273 } else {
274 r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->appData);
275 return_if_error(r, "BAD VALUE");
276 }
277
278 if (ifapi_get_sub_object(jso, "with_auth", &jso2)) {
279 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->with_auth);
280 return_if_error(r, "BAD VALUE");
281
282 } else {
283 out->with_auth = TPM2_NO;
284 }
285
286 if (!ifapi_get_sub_object(jso, "public", &jso2)) {
287 LOG_ERROR("Bad value");
288 return TSS2_FAPI_RC_BAD_VALUE;
289 }
290 r = ifapi_json_TPM2B_NV_PUBLIC_deserialize(jso2, &out->public);
291 return_if_error(r, "BAD VALUE");
292
293 if (!ifapi_get_sub_object(jso, "serialization", &jso2)) {
294 LOG_ERROR("Bad value");
295 return TSS2_FAPI_RC_BAD_VALUE;
296 }
297 r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->serialization);
298 return_if_error(r, "BAD VALUE");
299
300 if (!ifapi_get_sub_object(jso, "hierarchy", &jso2)) {
301 LOG_ERROR("Bad value");
302 return TSS2_FAPI_RC_BAD_VALUE;
303 }
304 r = ifapi_json_UINT32_deserialize(jso2, &out->hierarchy);
305 return_if_error(r, "BAD VALUE");
306
307 if (!ifapi_get_sub_object(jso, "policyInstance", &jso2)) {
308 LOG_ERROR("Bad value");
309 return TSS2_FAPI_RC_BAD_VALUE;
310 }
311 r = ifapi_json_char_deserialize(jso2, &out->policyInstance);
312 return_if_error(r, "BAD VALUE");
313
314 if (!ifapi_get_sub_object(jso, "description", &jso2)) {
315 LOG_ERROR("Bad value");
316 return TSS2_FAPI_RC_BAD_VALUE;
317 }
318 r = ifapi_json_char_deserialize(jso2, &out->description);
319 return_if_error(r, "BAD VALUE");
320
321 return_if_error(r, "BAD VALUE");
322 if (ifapi_get_sub_object(jso, "event_log", &jso2)) {
323 r = ifapi_json_char_deserialize(jso2, &out->event_log);
324 return_if_error(r, "BAD VALUE");
325
326 } else {
327 out->event_log = NULL;
328 }
329 LOG_TRACE("true");
330 return TSS2_RC_SUCCESS;
331 }
332
333 /** Deserialize a IFAPI_NV json object.
334 *
335 * @param[in] jso the json object to be deserialized.
336 * @param[out] out the deserialzed binary object.
337 * @retval TSS2_RC_SUCCESS if the function call was a success.
338 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
339 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
340 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
341 */
342 TSS2_RC
343 ifapi_json_IFAPI_HIERARCHY_deserialize(json_object *jso, IFAPI_HIERARCHY *out)
344 {
345 json_object *jso2;
346 TSS2_RC r;
347 LOG_TRACE("call");
348 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
349
350 if (ifapi_get_sub_object(jso, "with_auth", &jso2)) {
351 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->with_auth);
352 return_if_error(r, "BAD VALUE");
353
354 } else {
355 out->with_auth = TPM2_NO;
356 }
357
358 if (!ifapi_get_sub_object(jso, "authPolicy", &jso2)) {
359 LOG_ERROR("Bad value");
360 return TSS2_FAPI_RC_BAD_VALUE;
361 }
362 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->authPolicy);
363 return_if_error(r, "BAD VALUE");
364
365 if (!ifapi_get_sub_object(jso, "description", &jso2)) {
366 LOG_ERROR("Bad value");
367 return TSS2_FAPI_RC_BAD_VALUE;
368 }
369 r = ifapi_json_char_deserialize(jso2, &out->description);
370 return_if_error(r, "BAD VALUE");
371
372 LOG_TRACE("true");
373 return TSS2_RC_SUCCESS;
374 }
375
376 /** Deserialize a FAPI_QUOTE_INFO json object.
377 *
378 * @param[in] jso the json object to be deserialized.
379 * @param[out] out the deserialzed binary object.
380 * @retval TSS2_RC_SUCCESS if the function call was a success.
381 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
382 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
383 */
384 TSS2_RC
385 ifapi_json_FAPI_QUOTE_INFO_deserialize(json_object *jso, FAPI_QUOTE_INFO *out)
386 {
387 json_object *jso2;
388 TSS2_RC r;
389 LOG_TRACE("call");
390 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
391
392
393 if (!ifapi_get_sub_object(jso, "sig_scheme", &jso2)) {
394 LOG_ERROR("Bad value");
395 return TSS2_FAPI_RC_BAD_VALUE;
396 }
397 r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->sig_scheme);
398 return_if_error(r, "BAD VALUE");
399
400 if (!ifapi_get_sub_object(jso, "attest", &jso2)) {
401 LOG_ERROR("Bad value");
402 return TSS2_FAPI_RC_BAD_VALUE;
403 }
404 r = ifapi_json_TPMS_ATTEST_deserialize(jso2, &out->attest);
405 return_if_error(r, "BAD VALUE");
406 LOG_TRACE("true");
407 return TSS2_RC_SUCCESS;
408 }
409
410 /** Deserialize a IFAPI_DUPLICATE json object.
411 *
412 * @param[in] jso the json object to be deserialized.
413 * @param[out] out the deserialzed binary object.
414 * @retval TSS2_RC_SUCCESS if the function call was a success.
415 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
416 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
417 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
418 */
419 TSS2_RC
420 ifapi_json_IFAPI_DUPLICATE_deserialize(json_object *jso, IFAPI_DUPLICATE *out)
421 {
422 json_object *jso2;
423 TSS2_RC r;
424 LOG_TRACE("call");
425 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
426
427 if (!ifapi_get_sub_object(jso, "duplicate", &jso2)) {
428 LOG_ERROR("Bad value");
429 return TSS2_FAPI_RC_BAD_VALUE;
430 }
431
432 r = ifapi_json_TPM2B_PRIVATE_deserialize(jso2, &out->duplicate);
433 return_if_error(r, "BAD VALUE");
434
435 if (!ifapi_get_sub_object(jso, "encrypted_seed", &jso2)) {
436 LOG_ERROR("Bad value");
437 return TSS2_FAPI_RC_BAD_VALUE;
438 }
439 r = ifapi_json_TPM2B_ENCRYPTED_SECRET_deserialize(jso2, &out->encrypted_seed);
440 return_if_error(r, "BAD VALUE");
441
442 if (ifapi_get_sub_object(jso, "certificate", &jso2)) {
443 r = ifapi_json_char_deserialize(jso2, &out->certificate);
444 return_if_error(r, "BAD VALUE");
445
446 } else {
447 out->certificate = NULL;
448 }
449
450 if (!ifapi_get_sub_object(jso, "public", &jso2)) {
451 LOG_ERROR("Bad value");
452 return TSS2_FAPI_RC_BAD_VALUE;
453 }
454
455 r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public);
456 return_if_error(r, "BAD VALUE");
457 if (!ifapi_get_sub_object(jso, "public_parent", &jso2)) {
458 LOG_ERROR("Bad value");
459 return TSS2_FAPI_RC_BAD_VALUE;
460 }
461
462 r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public_parent);
463 return_if_error(r, "BAD VALUE");
464
465 if (ifapi_get_sub_object(jso, "policy", &jso2)) {
466 out->policy = calloc(1, sizeof(TPMS_POLICY));
467 goto_if_null2(out->policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
468 error_cleanup);
469
470 r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->policy);
471 goto_if_error(r, "Deserialize policy.", error_cleanup);
472 } else {
473 out->policy = NULL;
474 }
475
476 return TSS2_RC_SUCCESS;
477
478 error_cleanup:
479 SAFE_FREE(out->policy);
480 return r;
481 }
482
483 /** Deserialize a IFAPI_OBJECT_TYPE_CONSTANT json object.
484 *
485 * @param[in] jso the json object to be deserialized.
486 * @param[out] out the deserialzed binary object.
487 * @retval TSS2_RC_SUCCESS if the function call was a success.
488 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
489 */
490 TSS2_RC
491 ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_deserialize(json_object *jso,
492 IFAPI_OBJECT_TYPE_CONSTANT *out)
493 {
494 LOG_TRACE("call");
495 const char *token = json_object_get_string(jso);
496 int64_t i64;
497 if (get_number(token, &i64)) {
498 *out = (IFAPI_OBJECT_TYPE_CONSTANT) i64;
499 if ((int64_t)*out != i64) {
500 LOG_ERROR("Bad value");
501 return TSS2_FAPI_RC_BAD_VALUE;
502 }
503 return TSS2_RC_SUCCESS;
504 } else {
505 LOG_ERROR("Bad value");
506 return TSS2_FAPI_RC_BAD_VALUE;
507 }
508 }
509
510 /** Deserialize a IFAPI_OBJECT json object.
511 *
512 * @param[in] jso the json object to be deserialized.
513 * @param[out] out the deserialzed binary object.
514 * @retval TSS2_RC_SUCCESS if the function call was a success.
515 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
516 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
517 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
518 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
519 */
520 TSS2_RC
521 ifapi_json_IFAPI_OBJECT_deserialize(json_object *jso, IFAPI_OBJECT *out)
522 {
523 json_object *jso2;
524 TSS2_RC r;
525 LOG_TRACE("call");
526 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
527
528 if (!ifapi_get_sub_object(jso, "objectType", &jso2)) {
529 LOG_ERROR("Bad value");
530 return TSS2_FAPI_RC_BAD_VALUE;
531 }
532
533 r = ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_deserialize(jso2, &out->objectType);
534 return_if_error(r, "BAD VALUE");
535
536 switch (out->objectType) {
537 case IFAPI_NV_OBJ:
538 r = ifapi_json_IFAPI_NV_deserialize(jso, &out->misc.nv);
539 return_if_error(r, "BAD VALUE");
540 break;
541
542 case IFAPI_DUPLICATE_OBJ:
543 r = ifapi_json_IFAPI_DUPLICATE_deserialize(jso, &out->misc.key_tree);
544 return_if_error(r, "BAD VALUE");
545
546 break;
547
548 case IFAPI_EXT_PUB_KEY_OBJ:
549 r = ifapi_json_IFAPI_EXT_PUB_KEY_deserialize(jso, &out->misc.ext_pub_key);
550 return_if_error(r, "BAD VALUE");
551
552 break;
553
554 case IFAPI_HIERARCHY_OBJ:
555 r = ifapi_json_IFAPI_HIERARCHY_deserialize(jso, &out->misc.hierarchy);
556 return_if_error(r, "BAD VALUE");
557
558 break;
559 case IFAPI_KEY_OBJ:
560 r = ifapi_json_IFAPI_KEY_deserialize(jso, &out->misc.key);
561 return_if_error(r, "BAD VALUE");
562
563 break;
564 default:
565 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid call deserialize",
566 cleanup);
567 }
568
569 if (ifapi_get_sub_object(jso, "system", &jso2)) {
570 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->system);
571 return_if_error(r, "BAD VALUE");
572
573 } else {
574 out->system = TPM2_NO;
575 }
576
577 if (ifapi_get_sub_object(jso, "policy", &jso2)) {
578 out->policy = calloc(1, sizeof(TPMS_POLICY));
579 goto_if_null2(out->policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
580 cleanup);
581
582 r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->policy);
583 goto_if_error(r, "Deserialize policy.", cleanup);
584 } else {
585 out->policy = NULL;
586 }
587
588 return TSS2_RC_SUCCESS;
589
590 cleanup:
591 SAFE_FREE(out->policy);
592 return r;
593 }
594
595 /** Deserialize a IFAPI_EVENT_TYPE json object.
596 *
597 * @param[in] jso the json object to be deserialized.
598 * @param[out] out the deserialzed binary object.
599 * @retval TSS2_RC_SUCCESS if the function call was a success.
600 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
601 */
602 TSS2_RC
603 ifapi_json_IFAPI_EVENT_TYPE_deserialize(json_object *jso, IFAPI_EVENT_TYPE *out)
604 {
605 LOG_TRACE("call");
606 return ifapi_json_IFAPI_EVENT_TYPE_deserialize_txt(jso, out);
607 }
608
609 typedef struct {
610 IFAPI_EVENT_TYPE in;
611 char *name;
612 } IFAPI_IFAPI_EVENT_TYPE_ASSIGN;
613
614 static IFAPI_IFAPI_EVENT_TYPE_ASSIGN deserialize_IFAPI_EVENT_TYPE_tab[] = {
615 { IFAPI_IMA_EVENT_TAG, "ima-legacy" },
616 { IFAPI_TSS_EVENT_TAG, "tss2" },
617 };
618
619 /** Deserialize a json object of type IFAPI_EVENT_TYPE.
620 *
621 * @param[in] jso the json object to be deserialized.
622 * @param[out] out the deserialzed binary object.
623 * @retval TSS2_RC_SUCCESS if the function call was a success.
624 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
625 */
626 TSS2_RC
627 ifapi_json_IFAPI_EVENT_TYPE_deserialize_txt(json_object *jso,
628 IFAPI_EVENT_TYPE *out)
629 {
630 LOG_TRACE("call");
631 const char *token = json_object_get_string(jso);
632 int64_t i64;
633 if (get_number(token, &i64)) {
634 *out = (IFAPI_EVENT_TYPE) i64;
635 if ((int64_t)*out != i64) {
636 LOG_ERROR("Bad value");
637 return TSS2_FAPI_RC_BAD_VALUE;
638 }
639 return TSS2_RC_SUCCESS;
640
641 } else {
642 int itoken = get_token_start_idx(token);
643 size_t i;
644 size_t n = sizeof(deserialize_IFAPI_EVENT_TYPE_tab) /
645 sizeof(deserialize_IFAPI_EVENT_TYPE_tab[0]);
646 size_t size = strlen(token) - itoken;
647 for (i = 0; i < n; i++) {
648 if (strncasecmp(&token[itoken],
649 &deserialize_IFAPI_EVENT_TYPE_tab[i].name[0],
650 size) == 0) {
651 *out = deserialize_IFAPI_EVENT_TYPE_tab[i].in;
652 return TSS2_RC_SUCCESS;
653 }
654 }
655 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
656 }
657
658 }
659
660 /** Deserialize a IFAPI_TSS_EVENT json object.
661 *
662 * @param[in] jso the json object to be deserialized.
663 * @param[out] out the deserialzed binary object.
664 * @retval TSS2_RC_SUCCESS if the function call was a success.
665 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
666 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
667 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
668 */
669 TSS2_RC
670 ifapi_json_IFAPI_TSS_EVENT_deserialize(json_object *jso, IFAPI_TSS_EVENT *out)
671 {
672 json_object *jso2;
673 TSS2_RC r;
674 LOG_TRACE("call");
675 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
676
677 if (!ifapi_get_sub_object(jso, "data", &jso2)) {
678 LOG_ERROR("Bad value");
679 return TSS2_FAPI_RC_BAD_VALUE;
680 }
681 r = ifapi_json_TPM2B_EVENT_deserialize(jso2, &out->data);
682 return_if_error(r, "BAD VALUE");
683
684 if (!ifapi_get_sub_object(jso, "event", &jso2)) {
685 out->event = NULL;
686 } else {
687 /* out->event is a special case. It can be an arbitrary
688 JSON object. Since FAPI does not access its internals
689 we just store its string represenation here. */
690 out->event = strdup(json_object_to_json_string_ext(jso2,
691 JSON_C_TO_STRING_PRETTY));
692 return_if_null(out->event, "OOM", TSS2_FAPI_RC_MEMORY);
693 }
694 LOG_TRACE("true");
695 return TSS2_RC_SUCCESS;
696 }
697
698 /** Deserialize a IFAPI_IMA_EVENT json object.
699 *
700 * @param[in] jso the json object to be deserialized.
701 * @param[out] out the deserialzed binary object.
702 * @retval TSS2_RC_SUCCESS if the function call was a success.
703 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
704 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
705 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
706 */
707 TSS2_RC
708 ifapi_json_IFAPI_IMA_EVENT_deserialize(json_object *jso, IFAPI_IMA_EVENT *out)
709 {
710 json_object *jso2;
711 TSS2_RC r;
712 LOG_TRACE("call");
713 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
714
715 if (!ifapi_get_sub_object(jso, "eventData", &jso2)) {
716 LOG_ERROR("Bad value");
717 return TSS2_FAPI_RC_BAD_VALUE;
718 }
719 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->eventData);
720 return_if_error(r, "BAD VALUE");
721
722 if (!ifapi_get_sub_object(jso, "eventName", &jso2)) {
723 LOG_ERROR("Bad value");
724 return TSS2_FAPI_RC_BAD_VALUE;
725 }
726 r = ifapi_json_char_deserialize(jso2, &out->eventName);
727 return_if_error(r, "BAD VALUE");
728 LOG_TRACE("true");
729 return TSS2_RC_SUCCESS;
730 }
731
732 /** Deserialize a IFAPI_EVENT_UNION json object.
733 *
734 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
735 * @param[in] jso the json object to be deserialized.
736 * @param[in] selector the event type.
737 * @param[out] out the deserialzed binary object.
738 * @retval TSS2_RC_SUCCESS if the function call was a success.
739 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
740 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
741 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
742 */
743 TSS2_RC
744 ifapi_json_IFAPI_EVENT_UNION_deserialize(
745 UINT32 selector,
746 json_object *jso,
747 IFAPI_EVENT_UNION *out)
748 {
749 LOG_TRACE("call");
750 switch (selector) {
751 case IFAPI_TSS_EVENT_TAG:
752 return ifapi_json_IFAPI_TSS_EVENT_deserialize(jso, &out->tss_event);
753 case IFAPI_IMA_EVENT_TAG:
754 return ifapi_json_IFAPI_IMA_EVENT_deserialize(jso, &out->ima_event);
755 default:
756 LOG_TRACE("false");
757 return TSS2_FAPI_RC_BAD_VALUE;
758 };
759 }
760
761 /** Deserialize a IFAPI_EVENT json object.
762 *
763 * @param[in] jso the json object to be deserialized.
764 * @param[out] out the deserialzed binary object.
765 * @retval TSS2_RC_SUCCESS if the function call was a success.
766 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
767 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
768 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
769 */
770 TSS2_RC
771 ifapi_json_IFAPI_EVENT_deserialize(json_object *jso, IFAPI_EVENT *out)
772 {
773 json_object *jso2;
774 TSS2_RC r;
775 LOG_TRACE("call");
776 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
777
778 if (!ifapi_get_sub_object(jso, "recnum", &jso2)) {
779 LOG_ERROR("Bad value");
780 return TSS2_FAPI_RC_BAD_VALUE;
781 }
782 r = ifapi_json_UINT32_deserialize(jso2, &out->recnum);
783 return_if_error(r, "BAD VALUE");
784
785 if (!ifapi_get_sub_object(jso, "pcr", &jso2)) {
786 LOG_ERROR("Bad value");
787 return TSS2_FAPI_RC_BAD_VALUE;
788 }
789 r = ifapi_json_TPM2_HANDLE_deserialize(jso2, &out->pcr);
790 return_if_error(r, "BAD VALUE");
791
792 if (!ifapi_get_sub_object(jso, "digests", &jso2)) {
793 LOG_ERROR("Bad value");
794 return TSS2_FAPI_RC_BAD_VALUE;
795 }
796 r = ifapi_json_TPML_DIGEST_VALUES_deserialize(jso2, &out->digests);
797 return_if_error(r, "BAD VALUE");
798
799 if (!ifapi_get_sub_object(jso, "type", &jso2)) {
800 LOG_ERROR("Bad value");
801 return TSS2_FAPI_RC_BAD_VALUE;
802 }
803 r = ifapi_json_IFAPI_EVENT_TYPE_deserialize(jso2, &out->type);
804 return_if_error(r, "BAD VALUE");
805
806 if (!ifapi_get_sub_object(jso, "sub_event", &jso2)) {
807 LOG_ERROR("Bad value");
808 return TSS2_FAPI_RC_BAD_VALUE;
809 }
810 r = ifapi_json_IFAPI_EVENT_UNION_deserialize(out->type, jso2, &out->sub_event);
811 return_if_error(r, "BAD VALUE");
812 LOG_TRACE("true");
813 return TSS2_RC_SUCCESS;
814 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef IFAPI_JSON_DESERIALIZE_H
6 #define IFAPI_JSON_DESERIALIZE_H
7
8 #include <stdbool.h>
9 #include <json-c/json.h>
10 #include <json-c/json_util.h>
11
12 #include "tss2_tpm2_types.h"
13 #include "ifapi_keystore.h"
14 #include "fapi_int.h"
15
16 #define YES 1
17 #define NO 0
18
19 #define GET_OPTIONAL(name, json_name, type) \
20 if (!ifapi_get_sub_object(jso, json_name, &jso2)) { \
21 memset(&out->name, 0, sizeof(type)); \
22 } else { \
23 r = ifapi_json_ ## type ## _deserialize (jso2, &out->name); \
24 return_if_error(r,"BAD VALUE"); \
25 }
26
27 bool
28 ifapi_get_sub_object(json_object *jso, char *name, json_object **sub_jso);
29
30 TSS2_RC
31 ifapi_json_char_deserialize(json_object *jso, char **out);
32
33 TSS2_RC
34 ifapi_json_IFAPI_KEY_deserialize(json_object *jso, IFAPI_KEY *out);
35
36 TSS2_RC
37 ifapi_json_IFAPI_EXT_PUB_KEY_deserialize(json_object *jso,
38 IFAPI_EXT_PUB_KEY *out);
39
40 TSS2_RC
41 ifapi_json_IFAPI_NV_deserialize(json_object *jso, IFAPI_NV *out);
42
43 TSS2_RC
44 ifapi_json_IFAPI_HIERARCHY_deserialize(json_object *jso, IFAPI_HIERARCHY *out);
45
46 TSS2_RC
47 ifapi_json_IFAPI_OBJECT_deserialize(json_object *jso, IFAPI_OBJECT *out);
48
49 TSS2_RC
50 ifapi_json_FAPI_QUOTE_INFO_deserialize(json_object *jso, FAPI_QUOTE_INFO *out);
51
52 TSS2_RC
53 ifapi_json_IFAPI_EVENT_TYPE_deserialize(json_object *jso,
54 IFAPI_EVENT_TYPE *out);
55
56 TSS2_RC
57 ifapi_json_IFAPI_EVENT_TYPE_deserialize_txt(json_object *jso,
58 IFAPI_EVENT_TYPE *out);
59
60 TSS2_RC
61 ifapi_json_IFAPI_TSS_EVENT_deserialize(json_object *jso, IFAPI_TSS_EVENT *out);
62
63 TSS2_RC
64 ifapi_json_IFAPI_IMA_EVENT_deserialize(json_object *jso, IFAPI_IMA_EVENT *out);
65
66 TSS2_RC
67 ifapi_json_IFAPI_EVENT_UNION_deserialize(UINT32 selector, json_object *jso,
68 IFAPI_EVENT_UNION *out);
69
70 TSS2_RC
71 ifapi_json_IFAPI_EVENT_deserialize(json_object *jso, IFAPI_EVENT *out);
72
73 #endif /* IFAPI_JSON_DESERIALIZE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "ifapi_json_serialize.h"
14 #include "tpm_json_serialize.h"
15 #include "fapi_policy.h"
16 #include "ifapi_policy_json_serialize.h"
17
18 #define LOGMODULE fapijson
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22
23 /** Serialize a character string to json.
24 *
25 * @param[in] in value to be serialized.
26 * @param[out] jso pointer to the json object.
27 * @retval TSS2_RC_SUCCESS if the function call was a success.
28 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
29 */
30 TSS2_RC
31 ifapi_json_char_serialize(
32 const char *in,
33 json_object **jso)
34 {
35 if (in == NULL) {
36 *jso = json_object_new_string("");
37 } else {
38 *jso = json_object_new_string(in);
39 }
40 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
41 return TSS2_RC_SUCCESS;
42 }
43
44 /** Serialize value of type UINT8_ARY to json.
45 *
46 * @param[in] in value to be serialized.
47 * @param[out] jso pointer to the json object.
48 * @retval TSS2_RC_SUCCESS if the function call was a success.
49 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
50 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_DIGEST.
51 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
52 */
53 TSS2_RC
54 ifapi_json_UINT8_ARY_serialize(const UINT8_ARY *in, json_object **jso)
55 {
56 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
57
58 char hex_string[(in->size) * 2 + 1];
59
60 if (in->size > 0) {
61 uint8_t *buffer = in->buffer;
62
63 for (size_t i = 0, off = 0; i < in->size; i++, off += 2)
64 sprintf(&hex_string[off], "%02x", buffer[i]);
65 }
66 hex_string[(in->size) * 2] = '\0';
67 *jso = json_object_new_string(hex_string);
68 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
69
70 return TSS2_RC_SUCCESS;
71 }
72
73 /** Serialize value of type IFAPI_KEY to json.
74 *
75 * @param[in] in value to be serialized.
76 * @param[out] jso pointer to the json object.
77 * @retval TSS2_RC_SUCCESS if the function call was a success.
78 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
79 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_KEY.
80 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
81 */
82 TSS2_RC
83 ifapi_json_IFAPI_KEY_serialize(const IFAPI_KEY *in, json_object **jso)
84 {
85 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
86
87 TSS2_RC r;
88 json_object *jso2;
89
90 if (*jso == NULL)
91 *jso = json_object_new_object();
92 jso2 = NULL;
93 r = ifapi_json_TPMI_YES_NO_serialize(in->with_auth, &jso2);
94 return_if_error(r, "Serialize TPMI_YES_NO");
95
96 json_object_object_add(*jso, "with_auth", jso2);
97 jso2 = NULL;
98 r = ifapi_json_UINT32_serialize(in->persistent_handle, &jso2);
99 return_if_error(r, "Serialize UINT32");
100
101 json_object_object_add(*jso, "persistent_handle", jso2);
102 jso2 = NULL;
103 r = ifapi_json_TPM2B_PUBLIC_serialize(&in->public, &jso2);
104 return_if_error(r, "Serialize TPM2B_PUBLIC");
105
106 json_object_object_add(*jso, "public", jso2);
107 jso2 = NULL;
108 r = ifapi_json_UINT8_ARY_serialize(&in->serialization, &jso2);
109 return_if_error(r, "Serialize UINT8_ARY");
110
111 json_object_object_add(*jso, "serialization", jso2);
112 if (in->private.buffer != NULL) {
113 jso2 = NULL;
114 r = ifapi_json_UINT8_ARY_serialize(&in->private, &jso2);
115 return_if_error(r, "Serialize UINT8_ARY");
116
117 json_object_object_add(*jso, "private", jso2);
118 }
119 if (in->appData.buffer != NULL) {
120 jso2 = NULL;
121 r = ifapi_json_UINT8_ARY_serialize(&in->appData, &jso2);
122 return_if_error(r, "Serialize UINT8_ARY");
123
124 json_object_object_add(*jso, "appData", jso2);
125 }
126 jso2 = NULL;
127 r = ifapi_json_char_serialize(in->policyInstance, &jso2);
128 return_if_error(r, "Serialize char");
129
130 json_object_object_add(*jso, "policyInstance", jso2);
131
132 /* Creation Data is not available for imported keys */
133 if (in->creationData.size) {
134 jso2 = NULL;
135 r = ifapi_json_TPM2B_CREATION_DATA_serialize(&in->creationData, &jso2);
136 return_if_error(r, "Serialize TPM2B_CREATION_DATA");
137
138 json_object_object_add(*jso, "creationData", jso2);
139 }
140 /* Creation Ticket is not available for imported keys */
141 if (in->creationTicket.tag) {
142 jso2 = NULL;
143 r = ifapi_json_TPMT_TK_CREATION_serialize(&in->creationTicket, &jso2);
144 return_if_error(r, "Serialize TPMT_TK_CREATION");
145
146 json_object_object_add(*jso, "creationTicket", jso2);
147 }
148 jso2 = NULL;
149 r = ifapi_json_char_serialize(in->description, &jso2);
150 return_if_error(r, "Serialize char");
151
152 json_object_object_add(*jso, "description", jso2);
153 jso2 = NULL;
154 r = ifapi_json_char_serialize(in->certificate, &jso2);
155 return_if_error(r, "Serialize char");
156
157 json_object_object_add(*jso, "certificate", jso2);
158
159 if (in->public.publicArea.type != TPM2_ALG_KEYEDHASH) {
160 /* Keyed hash objects to not need a signing scheme. */
161 jso2 = NULL;
162 r = ifapi_json_TPMT_SIG_SCHEME_serialize(&in->signing_scheme, &jso2);
163 return_if_error(r, "Serialize TPMT_SIG_SCHEME");
164
165 json_object_object_add(*jso, "signing_scheme", jso2);
166 }
167 jso2 = NULL;
168 r = ifapi_json_TPM2B_NAME_serialize(&in->name, &jso2);
169 return_if_error(r, "Serialize TPM2B_NAME");
170
171 json_object_object_add(*jso, "name", jso2);
172 return TSS2_RC_SUCCESS;
173 }
174
175 /** Serialize value of type IFAPI_EXT_PUB_KEY to json.
176 *
177 * @param[in] in value to be serialized.
178 * @param[out] jso pointer to the json object.
179 * @retval TSS2_RC_SUCCESS if the function call was a success.
180 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
181 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_EXT_PUB_KEY.
182 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
183 */
184 TSS2_RC
185 ifapi_json_IFAPI_EXT_PUB_KEY_serialize(const IFAPI_EXT_PUB_KEY *in,
186 json_object **jso)
187 {
188 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
189
190 TSS2_RC r;
191 json_object *jso2;
192
193 if (*jso == NULL)
194 *jso = json_object_new_object();
195 jso2 = NULL;
196 r = ifapi_json_char_serialize(in->pem_ext_public, &jso2);
197 return_if_error(r, "Serialize char");
198
199 json_object_object_add(*jso, "pem_ext_public", jso2);
200 jso2 = NULL;
201 if (in->certificate) {
202 r = ifapi_json_char_serialize(in->certificate, &jso2);
203 return_if_error(r, "Serialize char");
204
205 json_object_object_add(*jso, "certificate", jso2);
206 }
207 if (in->public.publicArea.type) {
208 /* Public area was initialized */
209 jso2 = NULL;
210 r = ifapi_json_TPM2B_PUBLIC_serialize(&in->public, &jso2);
211 return_if_error(r, "Serialize TPM2B_PUBLIC");
212
213 json_object_object_add(*jso, "public", jso2);
214 }
215 return TSS2_RC_SUCCESS;
216 }
217
218 /** Serialize value of type IFAPI_NV to json.
219 *
220 * @param[in] in value to be serialized.
221 * @param[out] jso pointer to the json object.
222 * @retval TSS2_RC_SUCCESS if the function call was a success.
223 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
224 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_NV.
225 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
226 */
227 TSS2_RC
228 ifapi_json_IFAPI_NV_serialize(const IFAPI_NV *in, json_object **jso)
229 {
230 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
231
232 TSS2_RC r;
233 json_object *jso2;
234
235 if (*jso == NULL)
236 *jso = json_object_new_object();
237 jso2 = NULL;
238 r = ifapi_json_TPMI_YES_NO_serialize(in->with_auth, &jso2);
239 return_if_error(r, "Serialize TPMI_YES_NO");
240
241 json_object_object_add(*jso, "with_auth", jso2);
242
243 /* Add tag to classify json NV objects without deserialization */
244 jso2 = json_object_new_boolean(true);
245 json_object_object_add(*jso, "nv_object", jso2);
246
247 jso2 = NULL;
248 r = ifapi_json_TPM2B_NV_PUBLIC_serialize(&in->public, &jso2);
249 return_if_error(r, "Serialize TPM2B_NV_PUBLIC");
250
251 json_object_object_add(*jso, "public", jso2);
252 jso2 = NULL;
253 r = ifapi_json_UINT8_ARY_serialize(&in->serialization, &jso2);
254 return_if_error(r, "Serialize UINT8_ARY");
255
256 json_object_object_add(*jso, "serialization", jso2);
257 jso2 = NULL;
258 r = ifapi_json_UINT32_serialize(in->hierarchy, &jso2);
259 return_if_error(r, "Serialize UINT32");
260
261 json_object_object_add(*jso, "hierarchy", jso2);
262 jso2 = NULL;
263 r = ifapi_json_char_serialize(in->policyInstance, &jso2);
264 return_if_error(r, "Serialize char");
265
266 json_object_object_add(*jso, "policyInstance", jso2);
267 jso2 = NULL;
268 r = ifapi_json_char_serialize(in->description, &jso2);
269 return_if_error(r, "Serialize char");
270
271 json_object_object_add(*jso, "description", jso2);
272
273 if (in->appData.buffer != NULL) {
274 jso2 = NULL;
275 r = ifapi_json_UINT8_ARY_serialize(&in->appData, &jso2);
276 return_if_error(r, "Serialize UINT8_ARY");
277
278 json_object_object_add(*jso, "appData", jso2);
279 }
280 jso2 = NULL;
281 if (in->event_log) {
282 r = ifapi_json_char_serialize(in->event_log, &jso2);
283 return_if_error(r, "Serialize event log");
284
285 json_object_object_add(*jso, "event_log", jso2);
286 }
287 return TSS2_RC_SUCCESS;
288 }
289
290 /** Serialize value of type IFAPI_NV to json.
291 *
292 * @param[in] in value to be serialized.
293 * @param[out] jso pointer to the json object.
294 * @retval TSS2_RC_SUCCESS if the function call was a success.
295 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
296 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_NV.
297 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
298 */
299 TSS2_RC
300 ifapi_json_IFAPI_HIERARCHY_serialize(const IFAPI_HIERARCHY *in, json_object **jso)
301 {
302 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
303
304 TSS2_RC r;
305 json_object *jso2;
306
307 if (*jso == NULL)
308 *jso = json_object_new_object();
309 jso2 = NULL;
310 r = ifapi_json_TPMI_YES_NO_serialize(in->with_auth, &jso2);
311 return_if_error(r, "Serialize TPMI_YES_NO");
312
313 json_object_object_add(*jso, "with_auth", jso2);
314
315 jso2 = NULL;
316 r = ifapi_json_TPM2B_DIGEST_serialize(&in->authPolicy, &jso2);
317 return_if_error(r, "Serialize TPM2B_DIGEST");
318
319 json_object_object_add(*jso, "authPolicy", jso2);
320
321 jso2 = NULL;
322 r = ifapi_json_char_serialize(in->description, &jso2);
323 return_if_error(r, "Serialize char");
324
325 json_object_object_add(*jso, "description", jso2);
326
327 return TSS2_RC_SUCCESS;
328 }
329
330 /** Serialize value of type FAPI_QUOTE_INFO to json.
331 *
332 * @param[in] in value to be serialized.
333 * @param[out] jso pointer to the json object.
334 * @retval TSS2_RC_SUCCESS if the function call was a success.
335 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
336 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type FAPI_QUOTE_INFO.
337 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
338 */
339 TSS2_RC
340 ifapi_json_FAPI_QUOTE_INFO_serialize(const FAPI_QUOTE_INFO *in,
341 json_object **jso)
342 {
343 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
344
345 TSS2_RC r;
346 json_object *jso2;
347
348 if (*jso == NULL)
349 *jso = json_object_new_object();
350 jso2 = NULL;
351 r = ifapi_json_TPMT_SIG_SCHEME_serialize(&in->sig_scheme, &jso2);
352 return_if_error(r, "Serialize TPMT_SIG_SCHEME");
353
354 json_object_object_add(*jso, "sig_scheme", jso2);
355 jso2 = NULL;
356 r = ifapi_json_TPMS_ATTEST_serialize(&in->attest, &jso2);
357 return_if_error(r, "Serialize TPMS_ATTEST");
358
359 json_object_object_add(*jso, "attest", jso2);
360 return TSS2_RC_SUCCESS;
361 }
362
363
364 /** Serialize value of type IFAPI_DUPLICATE to json.
365 *
366 * @param[in] in value to be serialized.
367 * @param[out] jso pointer to the json object.
368 * @retval TSS2_RC_SUCCESS if the function call was a success.
369 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
370 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_DUPLICATE.
371 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
372 */
373 TSS2_RC
374 ifapi_json_IFAPI_DUPLICATE_serialize(const IFAPI_DUPLICATE *in,
375 json_object **jso)
376 {
377 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
378
379 TSS2_RC r;
380 json_object *jso2;
381
382 if (*jso == NULL)
383 *jso = json_object_new_object();
384 jso2 = NULL;
385 r = ifapi_json_TPM2B_PRIVATE_serialize(&in->duplicate, &jso2);
386 return_if_error(r, "Serialize TPM2B_PRIVATE");
387
388 json_object_object_add(*jso, "duplicate", jso2);
389 jso2 = NULL;
390 r = ifapi_json_TPM2B_ENCRYPTED_SECRET_serialize(&in->encrypted_seed, &jso2);
391 return_if_error(r, "Serialize TPM2B_ENCRYPTED_SECRET");
392
393 json_object_object_add(*jso, "encrypted_seed", jso2);
394 jso2 = NULL;
395 if (in->certificate) {
396 r = ifapi_json_char_serialize(in->certificate, &jso2);
397 return_if_error(r, "Serialize certificate");
398
399 json_object_object_add(*jso, "certificate", jso2);
400 }
401 jso2 = NULL;
402 r = ifapi_json_TPM2B_PUBLIC_serialize(&in->public, &jso2);
403 return_if_error(r, "Serialize TPM2B_PUBLIC");
404
405 json_object_object_add(*jso, "public", jso2);
406
407 jso2 = NULL;
408 r = ifapi_json_TPM2B_PUBLIC_serialize(&in->public_parent, &jso2);
409 return_if_error(r, "Serialize TPM2B_PUBLIC");
410
411 json_object_object_add(*jso, "public_parent", jso2);
412 if (in->policy) {
413 jso2 = NULL;
414 r = ifapi_json_TPMS_POLICY_serialize(in->policy, &jso2);
415 return_if_error(r, "Serialize policy");
416
417 json_object_object_add(*jso, "policy", jso2);
418 }
419
420 return TSS2_RC_SUCCESS;
421 }
422
423 /** Serialize value of type IFAPI_OBJECT_TYPE_CONSTANT to json.
424 *
425 * @param[in] in value to be serialized.
426 * @param[out] jso pointer to the json object.
427 * @retval TSS2_RC_SUCCESS if the function call was a success.
428 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
429 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2_HANDLE.
430 */
431 TSS2_RC
432 ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_serialize(const IFAPI_OBJECT_TYPE_CONSTANT
433 in, json_object **jso)
434 {
435 *jso = json_object_new_int(in);
436 if (*jso == NULL) {
437 LOG_ERROR("Bad value %"PRIx32 "", in);
438 return TSS2_FAPI_RC_BAD_VALUE;
439 }
440 return TSS2_RC_SUCCESS;
441 }
442
443 /** Serialize a IFAPI_OBJECT to json.
444 *
445 * @param[in] in value to be serialized.
446 * @param[out] jso pointer to the json object.
447 * @retval TSS2_RC_SUCCESS if the function call was a success.
448 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
449 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_OBJECT.
450 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
451 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
452 */
453 TSS2_RC
454 ifapi_json_IFAPI_OBJECT_serialize(const IFAPI_OBJECT *in,
455 json_object **jso)
456 {
457 TSS2_RC r;
458
459 if (*jso == NULL)
460 *jso = json_object_new_object();
461 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
462 json_object *jso2;
463
464 jso2 = NULL;
465 r = ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_serialize(in->objectType, &jso2);
466 return_if_error(r, "Serialize IFAPI_OBJECT");
467
468 json_object_object_add(*jso, "objectType", jso2);
469 jso2 = NULL;
470 r = ifapi_json_TPMI_YES_NO_serialize(in->system, &jso2);
471 return_if_error(r, "Serialize TPMI_YES_NO");
472
473 json_object_object_add(*jso, "system", jso2);
474
475 switch (in->objectType) {
476 case IFAPI_HIERARCHY_OBJ:
477 r = ifapi_json_IFAPI_HIERARCHY_serialize(&in->misc.hierarchy, jso);
478 return_if_error(r, "Error serialize FAPI hierarchy object");
479
480 break;
481 case IFAPI_NV_OBJ:
482 r = ifapi_json_IFAPI_NV_serialize(&in->misc.nv, jso);
483 return_if_error(r, "Error serialize FAPI NV object");
484
485 break;
486
487 case IFAPI_DUPLICATE_OBJ:
488 r = ifapi_json_IFAPI_DUPLICATE_serialize(&in->misc.key_tree, jso);
489 return_if_error(r, "Serialize IFAPI_OBJECT");
490
491 break;
492
493 case IFAPI_KEY_OBJ:
494 r = ifapi_json_IFAPI_KEY_serialize(&in->misc.key, jso);
495 return_if_error(r, "Error serialize FAPI KEY object");
496 break;
497
498 case IFAPI_EXT_PUB_KEY_OBJ:
499 r = ifapi_json_IFAPI_EXT_PUB_KEY_serialize(&in->misc.ext_pub_key, jso);
500 return_if_error(r, "Serialize IFAPI_OBJECT");
501
502 break;
503
504 default:
505 return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid call get_json");
506 }
507
508 if (in->policy) {
509 jso2 = NULL;
510 r = ifapi_json_TPMS_POLICY_serialize(in->policy, &jso2);
511 return_if_error(r, "Serialize policy");
512
513 json_object_object_add(*jso, "policy", jso2);
514 }
515
516 if (in->policy) {
517 jso2 = NULL;
518 r = ifapi_json_TPMS_POLICY_serialize(in->policy, &jso2);
519 return_if_error(r, "Serialize policy");
520
521 json_object_object_add(*jso, "policy", jso2);
522 }
523 return TSS2_RC_SUCCESS;
524 }
525
526 /** Serialize value of type IFAPI_CAP_INFO to json.
527 *
528 * @param[in] in value to be serialized.
529 * @param[out] jso pointer to the json object.
530 * @retval TSS2_RC_SUCCESS if the function call was a success.
531 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
532 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_INFO.
533 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
534 */
535 TSS2_RC
536 ifapi_json_IFAPI_CAP_INFO_serialize(const IFAPI_CAP_INFO *in, json_object **jso)
537 {
538 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
539
540 TSS2_RC r;
541 json_object *jso2;
542
543 if (*jso == NULL)
544 *jso = json_object_new_object();
545 jso2 = NULL;
546 r = ifapi_json_char_serialize(in->description, &jso2);
547 return_if_error(r, "Serialize char");
548
549 json_object_object_add(*jso, "description", jso2);
550
551 jso2 = NULL;
552 r = ifapi_json_TPMS_CAPABILITY_DATA_serialize(in->capability, &jso2);
553 return_if_error(r, "Serialize TPMS_CAPABILITY_DATA");
554
555 json_object_object_add(*jso, "info", jso2);
556
557 return TSS2_RC_SUCCESS;
558 }
559
560 /** Serialize value of type IFAPI_INFO to json.
561 *
562 * @param[in] in value to be serialized.
563 * @param[out] jso pointer to the json object.
564 * @retval TSS2_RC_SUCCESS if the function call was a success.
565 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
566 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_INFO.
567 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
568 */
569 TSS2_RC
570 ifapi_json_IFAPI_INFO_serialize(const IFAPI_INFO *in, json_object **jso)
571 {
572 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
573
574 TSS2_RC r;
575 json_object *jso2;
576 json_object *jso_cap_list;
577 size_t i;
578
579 if (*jso == NULL)
580 *jso = json_object_new_object();
581 jso2 = NULL;
582 r = ifapi_json_char_serialize(in->fapi_version, &jso2);
583 return_if_error(r, "Serialize char");
584
585 json_object_object_add(*jso, "version", jso2);
586 jso2 = NULL;
587 r = ifapi_json_char_serialize(in->fapi_config, &jso2);
588 return_if_error(r, "Serialize char");
589
590 json_object_object_add(*jso, "fapi_config", jso2);
591 jso_cap_list = json_object_new_array();
592
593 for (i = 0; i < IFAPI_MAX_CAP_INFO; i++) {
594 jso2 = NULL;
595 r = ifapi_json_IFAPI_CAP_INFO_serialize(&in->cap[i], &jso2);
596 return_if_error(r, "Serialize TPMS_CAPABILITY_DATA");
597
598 json_object_array_add(jso_cap_list, jso2);
599
600 }
601 json_object_object_add(*jso, "capabilities", jso_cap_list);
602
603 return TSS2_RC_SUCCESS;
604 }
605
606 /** Serialize IFAPI_EVENT_TYPE to json.
607 *
608 * @param[in] in constant to be serialized.
609 * @param[out] jso pointer to the json object.
610 * @retval TSS2_RC_SUCCESS if the function call was a success.
611 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
612 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type IFAPI_EVENT_TYPE.
613 */
614 TSS2_RC
615 ifapi_json_IFAPI_EVENT_TYPE_serialize(const IFAPI_EVENT_TYPE in,
616 json_object **jso)
617 {
618 return ifapi_json_IFAPI_EVENT_TYPE_serialize_txt(in, jso);
619 }
620
621 typedef struct {
622 IFAPI_EVENT_TYPE in;
623 char *name;
624 } IFAPI_EVENT_TYPE_ASSIGN;
625
626 static IFAPI_EVENT_TYPE_ASSIGN serialize_IFAPI_EVENT_TYPE_tab[] = {
627 { IFAPI_IMA_EVENT_TAG, "ima-legacy" },
628 { IFAPI_TSS_EVENT_TAG, "tss2" },
629 };
630
631 /** Get json object for a constant, if a variable is actually of type IFAPI_EVENT_TYPE.
632 *
633 * @param[in] in binary value of constant.
634 * @param[out] str_jso object with text representing the constant.
635 * @retval TSS2_RC_SUCCESS if the function call was a success.
636 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
637 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type IFAPI_EVENT_TYPE.
638 */
639 TSS2_RC
640 ifapi_json_IFAPI_EVENT_TYPE_serialize_txt(
641 const IFAPI_EVENT_TYPE in,
642 json_object **str_jso)
643 {
644 size_t n = sizeof(serialize_IFAPI_EVENT_TYPE_tab) / sizeof(
645 serialize_IFAPI_EVENT_TYPE_tab[0]);
646 size_t i;
647 for (i = 0; i < n; i++) {
648 if (serialize_IFAPI_EVENT_TYPE_tab[i].in == in) {
649 *str_jso = json_object_new_string(serialize_IFAPI_EVENT_TYPE_tab[i].name);
650 return_if_null(str_jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
651
652 return TSS2_RC_SUCCESS;
653 }
654 }
655 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
656 }
657
658 /** Serialize value of type IFAPI_TSS_EVENT to json.
659 *
660 * @param[in] in value to be serialized.
661 * @param[out] jso pointer to the json object.
662 * @retval TSS2_RC_SUCCESS if the function call was a success.
663 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
664 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_TSS_EVENT.
665 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
666 */
667 TSS2_RC
668 ifapi_json_IFAPI_TSS_EVENT_serialize(const IFAPI_TSS_EVENT *in,
669 json_object **jso)
670 {
671 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
672
673 TSS2_RC r;
674 json_object *jso2;
675
676 if (*jso == NULL)
677 *jso = json_object_new_object();
678 jso2 = NULL;
679 r = ifapi_json_TPM2B_EVENT_serialize(&in->data, &jso2);
680 return_if_error(r, "Serialize TPM2B_EVENT");
681
682 json_object_object_add(*jso, "data", jso2);
683
684 if (in->event) {
685 /* The in->event field is somewhat special. Its an arbitrary json
686 object that shall be serialized under the event field. Thus we
687 first have to deserialize the string before we can add it to
688 the data structure. */
689 jso2 = json_tokener_parse(in->event);
690 return_if_null(jso2, "Event is not valid JSON.", TSS2_FAPI_RC_BAD_VALUE);
691
692 json_object_object_add(*jso, "event", jso2);
693 }
694 return TSS2_RC_SUCCESS;
695 }
696
697 /** Serialize value of type IFAPI_IMA_EVENT to json.
698 *
699 * @param[in] in value to be serialized.
700 * @param[out] jso pointer to the json object.
701 * @retval TSS2_RC_SUCCESS if the function call was a success.
702 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
703 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_IMA_EVENT.
704 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
705 */
706 TSS2_RC
707 ifapi_json_IFAPI_IMA_EVENT_serialize(const IFAPI_IMA_EVENT *in,
708 json_object **jso)
709 {
710 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
711
712 TSS2_RC r;
713 json_object *jso2;
714
715 if (*jso == NULL)
716 *jso = json_object_new_object();
717 jso2 = NULL;
718 r = ifapi_json_TPM2B_DIGEST_serialize(&in->eventData, &jso2);
719 return_if_error(r, "Serialize TPM2B_DIGEST");
720
721 json_object_object_add(*jso, "eventData", jso2);
722 jso2 = NULL;
723 r = ifapi_json_char_serialize(in->eventName, &jso2);
724 return_if_error(r, "Serialize char");
725
726 json_object_object_add(*jso, "eventName", jso2);
727 return TSS2_RC_SUCCESS;
728 }
729
730 /** Serialize a IFAPI_EVENT_UNION to json.
731 *
732 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
733 * @param[in] in the value to be serialized.
734 * @param[in] selector the type of the event.
735 * @param[out] jso pointer to the json object.
736 * @retval TSS2_RC_SUCCESS if the function call was a success.
737 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
738 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_EVENT_UNION.
739 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
740 */
741 TSS2_RC
742 ifapi_json_IFAPI_EVENT_UNION_serialize(const IFAPI_EVENT_UNION *in,
743 UINT32 selector, json_object **jso)
744 {
745 if (*jso == NULL)
746 *jso = json_object_new_object();
747 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
748
749 switch (selector) {
750 case IFAPI_TSS_EVENT_TAG:
751 return ifapi_json_IFAPI_TSS_EVENT_serialize(&in->tss_event, jso);
752 case IFAPI_IMA_EVENT_TAG:
753 return ifapi_json_IFAPI_IMA_EVENT_serialize(&in->ima_event, jso);
754 default:
755 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
756 return TSS2_SYS_RC_BAD_VALUE;
757 };
758 return TSS2_RC_SUCCESS;
759 }
760
761 /** Serialize value of type IFAPI_EVENT to json.
762 *
763 * @param[in] in value to be serialized.
764 * @param[out] jso pointer to the json object.
765 * @retval TSS2_RC_SUCCESS if the function call was a success.
766 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
767 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type IFAPI_EVENT.
768 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
769 */
770 TSS2_RC
771 ifapi_json_IFAPI_EVENT_serialize(const IFAPI_EVENT *in, json_object **jso)
772 {
773 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
774
775 TSS2_RC r;
776 json_object *jso2;
777
778 if (*jso == NULL)
779 *jso = json_object_new_object();
780 jso2 = NULL;
781 r = ifapi_json_UINT32_serialize(in->recnum, &jso2);
782 return_if_error(r, "Serialize UINT32");
783
784 json_object_object_add(*jso, "recnum", jso2);
785 jso2 = NULL;
786 r = ifapi_json_TPM2_HANDLE_serialize(in->pcr, &jso2);
787 return_if_error(r, "Serialize TPM2_HANDLE");
788
789 json_object_object_add(*jso, "pcr", jso2);
790 jso2 = NULL;
791 r = ifapi_json_TPML_DIGEST_VALUES_serialize(&in->digests, &jso2);
792 return_if_error(r, "Serialize TPML_DIGEST");
793
794 json_object_object_add(*jso, "digests", jso2);
795 jso2 = NULL;
796 r = ifapi_json_IFAPI_EVENT_TYPE_serialize(in->type, &jso2);
797 return_if_error(r, "Serialize IFAPI_EVENT_TYPE");
798
799 json_object_object_add(*jso, "type", jso2);
800 jso2 = NULL;
801 r = ifapi_json_IFAPI_EVENT_UNION_serialize(&in->sub_event, in->type, &jso2);
802 return_if_error(r, "Serialize IFAPI_EVENT_UNION");
803
804 json_object_object_add(*jso, "sub_event", jso2);
805 return TSS2_RC_SUCCESS;
806 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef IFAPI_JSON_SERIALIZE_H
6 #define IFAPI_JSON_SERIALIZE_H
7
8 #include <stdbool.h>
9 #include <json-c/json.h>
10 #include <json-c/json_util.h>
11
12 #include "tss2_tpm2_types.h"
13 #include "fapi_int.h"
14 #include "ifapi_keystore.h"
15
16 #define YES 1
17 #define NO 0
18
19 TSS2_RC
20 ifapi_json_UINT8_ARY_serialize(const UINT8_ARY *in, json_object **jso);
21
22 TSS2_RC
23 ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_serialize(const IFAPI_OBJECT_TYPE_CONSTANT
24 in, json_object **jso);
25
26 TSS2_RC
27 ifapi_json_IFAPI_KEY_serialize(const IFAPI_KEY *in, json_object **jso);
28
29 TSS2_RC
30 ifapi_json_IFAPI_EXT_PUB_KEY_serialize(const IFAPI_EXT_PUB_KEY *in,
31 json_object **jso);
32
33 TSS2_RC
34 ifapi_json_IFAPI_NV_serialize(const IFAPI_NV *in, json_object **jso);
35
36 TSS2_RC
37 ifapi_json_IFAPI_HIERARCHY_serialize(const IFAPI_HIERARCHY *in, json_object **jso);
38
39 TSS2_RC
40 ifapi_json_IFAPI_OBJECT_serialize(const IFAPI_OBJECT *in,
41 json_object **jso);
42
43 TSS2_RC
44 ifapi_json_FAPI_QUOTE_INFO_serialize(const FAPI_QUOTE_INFO *in,
45 json_object **jso);
46
47 TSS2_RC
48 ifapi_json_IFAPI_DUPLICATE_serialize(const IFAPI_DUPLICATE *in,
49 json_object **jso);
50 TSS2_RC
51 ifapi_json_IFAPI_CAP_INFO_serialize(const IFAPI_CAP_INFO *in, json_object **jso);
52
53 TSS2_RC
54 ifapi_json_IFAPI_INFO_serialize(const IFAPI_INFO *in, json_object **jso);
55
56 TSS2_RC
57 ifapi_json_IFAPI_EVENT_TYPE_serialize(const IFAPI_EVENT_TYPE in,
58 json_object **jso);
59
60 TSS2_RC
61 ifapi_json_IFAPI_EVENT_TYPE_serialize_txt(const IFAPI_EVENT_TYPE in,
62 json_object **jso);
63
64 TSS2_RC
65 ifapi_json_IFAPI_TSS_EVENT_serialize(const IFAPI_TSS_EVENT *in,
66 json_object **jso);
67
68 TSS2_RC
69 ifapi_json_IFAPI_IMA_EVENT_serialize(const IFAPI_IMA_EVENT *in,
70 json_object **jso);
71
72 TSS2_RC
73 ifapi_json_IFAPI_EVENT_UNION_serialize(const IFAPI_EVENT_UNION *in,
74 UINT32 selector, json_object **jso);
75
76 TSS2_RC
77 ifapi_json_IFAPI_EVENT_serialize(const IFAPI_EVENT *in, json_object **jso);
78
79 #endif /* IFAPI_JSON_SERIALIZE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #include <dirent.h>
9 #endif
10
11 #include "ifapi_io.h"
12 #include "ifapi_helpers.h"
13 #include "ifapi_keystore.h"
14 #define LOGMODULE fapi
15 #include "util/log.h"
16 #include "util/aux_util.h"
17 #include "ifapi_json_deserialize.h"
18 #include "ifapi_json_serialize.h"
19
20 /** Initialize the linked list for an explicit key path.
21 *
22 * An implicit key path will be expanded to a key path starting with the profile
23 * directory. Missing parts will be added if possible.
24 * A linked list of the directories of the explicit path will be returned.
25 *
26 * @param[in] context_profile The profile name used for expansion of the
27 * implicit key path.
28 * @param[in] ipath the implicit key path which has to be expanded.
29 * @param[out] list_node1 The first directory of the implicit list.
30 * @param[out] current_list_node The tail of the path list after the path
31 * which was expanded.
32 * @param[out] result The list of directories as linked list.
33 * @retval TSS2_RC_SUCCESS If the explicit path was created.
34 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
35 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
36 * implicit path.
37 */
38 static TSS2_RC
39 initialize_explicit_key_path(
40 const char *context_profile,
41 const char *ipath,
42 NODE_STR_T **list_node1,
43 NODE_STR_T **current_list_node,
44 NODE_STR_T **result)
45 {
46 *list_node1 = split_string(ipath, IFAPI_FILE_DELIM);
47 NODE_STR_T *list_node = *list_node1;
48 char const *profile;
49 char *hierarchy;
50 TSS2_RC r = TSS2_RC_SUCCESS;
51
52 *result = NULL;
53 if (list_node == NULL) {
54 LOG_ERROR("Invalid path");
55 free_string_list(*list_node1);
56 return TSS2_FAPI_RC_BAD_VALUE;
57 }
58 /* Check whether profile is part of the implicit path. */
59 if (strncmp("P_", list_node->str, 2) == 0) {
60 profile = list_node->str;
61 list_node = list_node->next;
62 } else {
63 profile = context_profile;
64 }
65 /* Create the initial node of the linked list. */
66 *result = init_string_list(profile);
67 if (*result == NULL) {
68 free_string_list(*list_node1);
69 LOG_ERROR("Out of memory");
70 return TSS2_FAPI_RC_MEMORY;
71 }
72 if (list_node == NULL) {
73 /* Storage hierarchy will be used as default. */
74 hierarchy = "HS";
75 } else {
76 if (strcmp(list_node->str, "HS") == 0 ||
77 strcmp(list_node->str, "HE") == 0 ||
78 strcmp(list_node->str, "HP") == 0 ||
79 strcmp(list_node->str, "HN") == 0 ||
80 strcmp(list_node->str, "HP") == 0) {
81 hierarchy = list_node->str;
82 list_node = list_node->next;
83 } else if (strcmp(list_node->str, "EK") == 0) {
84 /* The hierarchy for an endorsement key will be added. */
85 hierarchy = "HE";
86 } else if (list_node->next != NULL &&
87 (strcmp(list_node->str, "SRK") == 0 ||
88 strcmp(list_node->str, "SDK") == 0 ||
89 strcmp(list_node->str, "UNK") == 0 ||
90 strcmp(list_node->str, "UDK") == 0)) {
91 /* The storage hierachy will be added. */
92 hierarchy = "HS";
93 } else {
94 hierarchy = "HS";
95 }
96 }
97 /* Add the used hierarcy to the linked list. */
98 if (!add_string_to_list(*result, hierarchy)) {
99 LOG_ERROR("Out of memory");
100 r = TSS2_FAPI_RC_MEMORY;
101 goto error;
102 }
103 if (list_node == NULL) {
104 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Explicit path can't be determined.",
105 error);
106 }
107 /* Add the primary directory to the linked list. */
108 if (!add_string_to_list(*result, list_node->str)) {
109 LOG_ERROR("Out of memory");
110 r = TSS2_FAPI_RC_MEMORY;
111 goto error;
112 }
113 /* Return the rest of the path. */
114 *current_list_node = list_node->next;
115 return TSS2_RC_SUCCESS;
116
117 error:
118 free_string_list(*result);
119 *result = NULL;
120 free_string_list(*list_node1);
121 *list_node1 = NULL;
122 return r;
123 }
124
125 /** Get explicit key path as linked list.
126 *
127 * An implicit key path will be expanded to a key path starting with the profile
128 * directory. Missing parts will be added if possible.
129 * A linked list of the directories of the explicit path will be returned.
130 * @param[in] keystore The key directories and default profile.
131 * @param[in] ipath the implicit key path which has to be expanded.
132 * @param[out] result The list of directories as linked list.
133 * @retval TSS2_RC_SUCCESS If the explicit path was created.
134 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
135 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
136 * implicit path.
137 */
138 static TSS2_RC
139 get_explicit_key_path(
140 IFAPI_KEYSTORE *keystore,
141 const char *ipath,
142 NODE_STR_T **result)
143 {
144 NODE_STR_T *list_node1 = NULL;
145 NODE_STR_T *list_node = NULL;
146 TSS2_RC r = initialize_explicit_key_path(keystore->defaultprofile, ipath,
147 &list_node1, &list_node, result);
148 goto_if_error(r, "init_explicit_key_path", error);
149
150 while (list_node != NULL) {
151 /* Add tail of path list to expanded head of the path list. */
152 if (!add_string_to_list(*result, list_node->str)) {
153 LOG_ERROR("Out of memory");
154 r = TSS2_FAPI_RC_MEMORY;
155 goto error;
156 }
157 list_node = list_node->next;
158 }
159 free_string_list(list_node1);
160 return TSS2_RC_SUCCESS;
161
162 error:
163 if (*result)
164 free_string_list(*result);
165 if (list_node1)
166 free_string_list(list_node1);
167 return r;
168 }
169
170 /** Convert full FAPI path to relative path.
171 *
172 * The relative path will be copied directly into the passed object.
173 *
174 * @param[in] keystore The key directories and default profile.
175 * @param[in,out] path The absolute path.
176 */
177 void
178 full_path_to_fapi_path(IFAPI_KEYSTORE *keystore, char *path)
179 {
180 unsigned int start_pos, end_pos, i;
181 const unsigned int path_length = strlen(path);
182 size_t keystore_length = strlen(keystore->userdir);
183 char fapi_path_delim;
184
185 start_pos = 0;
186
187 /* Check type of path, user or system */
188 if (strncmp(&path[0], keystore->userdir, keystore_length) == 0) {
189 start_pos = strlen(keystore->userdir);
190 } else {
191 keystore_length = strlen(keystore->systemdir);
192 if (strncmp(&path[0], keystore->systemdir, keystore_length) == 0)
193 start_pos = strlen(keystore->systemdir);
194 }
195
196 if (!start_pos)
197 /* relative path was passed */
198 return;
199
200 /* Move relative path */
201 end_pos = path_length - start_pos;
202 memmove(&path[0], &path[start_pos], end_pos);
203 size_t ip = 0;
204 size_t lp = strlen(path);
205
206 /* Remove double / */
207 while (ip < lp) {
208 if (strncmp(&path[ip], "//", 2) == 0) {
209 memmove(&path[ip], &path[ip+1], lp-ip);
210 lp -= 1;
211 } else {
212 ip += 1;
213 }
214 }
215
216 /* A relative policy path will end before the file extension.
217 For other objects only the directory name will be uses as
218 relative name. */
219 if (ifapi_path_type_p(path, IFAPI_POLICY_PATH))
220 fapi_path_delim = '.';
221 else
222 fapi_path_delim = IFAPI_FILE_DELIM_CHAR;
223
224 for (i = end_pos - 2; i > 0; i--) {
225 if (path[i] == fapi_path_delim) {
226 path[i] = '\0';
227 break;
228 }
229 }
230 }
231
232 /** Expand key store path.
233 *
234 * Depending on the type of the passed path the path will be expanded. For hierarchies
235 * the profile directory will be added. For keys the implicit path will
236 * be expanded to an explicit path with all directories.
237 * @param[in] keystore The key directories and default profile.
238 * @param[in] path the implicit path which has to be expanded if possible.
239 * @param[out] file_name The explicit path (callee-allocated)
240 * @retval TSS2_RC_SUCCESS If the explicit path was created.
241 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
242 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
243 * implicit path.
244 */
245 static TSS2_RC
246 expand_path(IFAPI_KEYSTORE *keystore, const char *path, char **file_name)
247 {
248 TSS2_RC r;
249 NODE_STR_T *node_list = NULL;
250 size_t pos = 0;
251
252 if (ifapi_hierarchy_path_p(path)) {
253 if (strncmp(path, "P_", 2) == 0 || strncmp(path, "/P_", 3) == 0) {
254 *file_name = strdup(path);
255 return_if_null(*file_name, "Out of memory", TSS2_FAPI_RC_MEMORY);
256 } else {
257 if (strncmp("/", path, 1) == 0)
258 pos = 1;
259 r = ifapi_asprintf(file_name, "%s%s%s", keystore->defaultprofile,
260 IFAPI_FILE_DELIM, &path[pos]);
261 return_if_error(r, "Out of memory.");
262 }
263 } else if (ifapi_path_type_p(path, IFAPI_NV_PATH)
264 || ifapi_path_type_p(path, IFAPI_POLICY_PATH)
265 || ifapi_path_type_p(path, IFAPI_EXT_PATH)
266 || strncmp(path, "/P_", 3) == 0 || strncmp(path, "P_", 2) == 0) {
267 *file_name = strdup(path);
268 return_if_null(*file_name, "Out of memory", TSS2_FAPI_RC_MEMORY);
269
270 } else {
271 r = get_explicit_key_path(keystore, path, &node_list);
272 return_if_error(r, "Out of memory");
273
274 r = ifapi_path_string(file_name, NULL, node_list, NULL);
275 goto_if_error(r, "Out of memory", error);
276
277 free_string_list(node_list);
278 }
279 return TSS2_RC_SUCCESS;
280
281 error:
282 free_string_list(node_list);
283 return r;
284 }
285 /** Expand FAPI path to object path.
286 *
287 * The object file name will be appended and the implicit path will be expanded
288 * if possible.
289 * FAPI object path names correspond to directories of the key store. The
290 * objects are stored in a certain file in this directory. This function
291 * appends the name of the object file to the FAPI directory to prepare file IO.
292 * @retval TSS2_RC_SUCCESS If the object file path can be created.
293 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path name cannot allocated.
294 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
295 * implicit path.
296 */
297 static TSS2_RC
298 expand_path_to_object(
299 IFAPI_KEYSTORE *keystore,
300 const char *path,
301 const char *dir,
302 char **file_name)
303 {
304
305 TSS2_RC r;
306 char *expanded_path = NULL;
307
308 /* Expand implicit path to explicit path. */
309 r = expand_path(keystore, path, &expanded_path);
310 return_if_error(r, "Expand path");
311
312 /* Append object file. */
313 r = ifapi_asprintf(file_name, "%s/%s/%s", dir, expanded_path, IFAPI_OBJECT_FILE);
314 SAFE_FREE(expanded_path);
315 return r;
316 }
317
318 /** Store keystore parameters in the keystore context.
319 *
320 * Also the user directory will be created if it does not exist.
321 *
322 * @param[out] keystore The keystore to be initialized.
323 * @param[in] config_systemdir The configured system directory.
324 * @param[in] config_userdir The configured user directory.
325 * @param[in] config_defaultprofile The configured profile.
326 *
327 * @retval TSS2_RC_SUCCESS If the keystore can be initialized.
328 * @retval TSS2_FAPI_RC_IO_ERROR If the user part of the keystore can't be
329 * initialized.
330 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
331 * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
332 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
333 * the function.
334 */
335 TSS2_RC
336 ifapi_keystore_initialize(
337 IFAPI_KEYSTORE *keystore,
338 const char *config_systemdir,
339 const char *config_userdir,
340 const char *config_defaultprofile)
341 {
342 TSS2_RC r;
343 char *home_dir;
344 char *home_path = NULL;
345 size_t start_pos;
346
347 memset(keystore, 0, sizeof(IFAPI_KEYSTORE));
348
349 /* Check whether usage of home directory is provided in config file */
350 if (strncmp("~", config_userdir, 1) == 0) {
351 start_pos = 1;
352 } else if (strncmp("$HOME", config_userdir, 5) == 0) {
353 start_pos = 5;
354 } else {
355 start_pos = 0;
356 }
357
358 /* Replace home abbreviation in user path. */
359 if (start_pos) {
360 LOG_DEBUG("Expanding user directory %s to user's home", config_userdir);
361 home_dir = getenv("HOME");
362 goto_if_null2(home_dir, "Home directory can't be determined.",
363 r, TSS2_FAPI_RC_BAD_PATH, error);
364
365 r = ifapi_asprintf(&home_path, "%s%s%s", home_dir, IFAPI_FILE_DELIM,
366 &config_userdir[start_pos]);
367 goto_if_error(r, "Out of memory.", error);
368 keystore->userdir = home_path;
369
370 } else {
371 keystore->userdir = strdup(config_userdir);
372 goto_if_null2(keystore->userdir, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
373 error);
374 }
375
376 /* Create user directory if necessary */
377 r = ifapi_io_check_create_dir(keystore->userdir);
378 goto_if_error2(r, "User directory %s can't be created.", error, keystore->userdir);
379
380 keystore->systemdir = strdup(config_systemdir);
381 goto_if_null2(keystore->systemdir, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
382 error);
383
384 keystore->defaultprofile = strdup(config_defaultprofile);
385 goto_if_null2(keystore->defaultprofile, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
386 error);
387
388 SAFE_FREE(home_path);
389 return TSS2_RC_SUCCESS;
390
391 error:
392 SAFE_FREE(keystore->defaultprofile);
393 SAFE_FREE(keystore->userdir);
394 SAFE_FREE(keystore->systemdir);
395 return r;
396 }
397
398 /** Get absolute object path for FAPI relative path and check whether file exists.
399 *
400 * It will be checked whether object exists in user directory, if no
401 * the path in system directory will be returnde
402 *
403 * @param[in] keystore The key directories and default profile.
404 * @param[in] rel_path The relative path of the object. For keys the path will
405 * expanded if possible.
406 * @param[out] abs_path The absolute path of the object.
407 * @retval TSS2_RC_SUCCESS If the object can be read.
408 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if the file does not exist (for key objects).
409 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist (for NV and hierarchy objects).
410 * @retval TSS2_FAPI_RC_IO_ERROR: If the file could not be read by the IO module.
411 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
412 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
413 * the function.
414 */
415 static TSS2_RC
416 rel_path_to_abs_path(
417 IFAPI_KEYSTORE *keystore,
418 const char *rel_path,
419 char **abs_path)
420 {
421 TSS2_RC r;
422 char *directory = NULL;
423
424 /* First expand path in user directory */
425 r = expand_path(keystore, rel_path, &directory);
426 goto_if_error(r, "Expand path", cleanup);
427
428 r = expand_path_to_object(keystore, directory,
429 keystore->userdir, abs_path);
430 goto_if_error2(r, "Object path %s could not be created.", cleanup, directory);
431
432
433 if (!ifapi_io_path_exists(*abs_path)) {
434 /* Second try system directory if object not found in user directory */
435 SAFE_FREE(*abs_path);
436 r = expand_path_to_object(keystore, directory,
437 keystore->systemdir, abs_path);
438 goto_if_error2(r, "Object path %s could not be created.", cleanup, directory);
439
440 if (ifapi_io_path_exists(*abs_path)) {
441 r = TSS2_RC_SUCCESS;
442 goto cleanup;
443 }
444
445 /* Check type of object which does not exist. */
446 if (ifapi_path_type_p(rel_path, IFAPI_NV_PATH) ||
447 (ifapi_hierarchy_path_p(rel_path))) {
448 /* Hierarchy which should be created during provisioning could not be loaded. */
449 goto_error(r, TSS2_FAPI_RC_PATH_NOT_FOUND,
450 "Keystore not initialized. Hierarchy file %s does not exist.",
451 cleanup, rel_path);
452 } else {
453 /* Object file for key does not exist in keystore */
454 goto_error(r, TSS2_FAPI_RC_KEY_NOT_FOUND,
455 "Key %s not found.", cleanup, rel_path);
456 }
457 }
458
459 cleanup:
460 SAFE_FREE(directory);
461 return r;
462 }
463
464 /** Start loading FAPI object from key store.
465 *
466 * Keys objects, NV objects, and hierarchies can be loaded.
467 *
468 * @param[in] keystore The key directories and default profile.
469 * @param[in] io The input/output context being used for file I/O.
470 * @param[in] path The relative path of the object. For keys the path will
471 * expanded if possible.
472 * @retval TSS2_RC_SUCCESS If the object can be read.
473 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered.
474 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist.
475 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
476 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
477 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
478 * the function.
479 */
480 TSS2_RC
481 ifapi_keystore_load_async(
482 IFAPI_KEYSTORE *keystore,
483 IFAPI_IO *io,
484 const char *path)
485 {
486 TSS2_RC r;
487 char *abs_path = NULL;
488
489 LOG_TRACE("Load object: %s", path);
490
491 /* Free old input buffer if buffer exists */
492 SAFE_FREE(io->char_rbuffer);
493
494 /* Convert relative path to absolute path in keystore */
495 r = rel_path_to_abs_path(keystore, path, &abs_path);
496 goto_if_error2(r, "Object %s not found.", cleanup, path);
497
498 /* Prepare read operation */
499 r = ifapi_io_read_async(io, abs_path);
500
501 cleanup:
502 SAFE_FREE(abs_path);
503 return r;
504 }
505
506 /** Finish loading FAPI object from key store.
507 *
508 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
509 *
510 * @param[in] keystore The key directories and default profile.
511 * @param[in,out] io The input/output context being used for file I/O.
512 * @param[in] object The caller allocated object which will loaded from keystore.
513 * @retval TSS2_RC_SUCCESS After successfully loading the object.
514 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
515 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
516 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
517 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
518 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
519 * the function.
520 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
521 */
522 TSS2_RC
523 ifapi_keystore_load_finish(
524 IFAPI_KEYSTORE *keystore,
525 IFAPI_IO *io,
526 IFAPI_OBJECT *object)
527 {
528 TSS2_RC r;
529 json_object *jso = NULL;
530 uint8_t *buffer = NULL;
531 /* Keystore parameter is used to be prepared if transmission of state information
532 between async and finish will be necessary in future extensions. */
533 (void)keystore;
534
535 r = ifapi_io_read_finish(io, &buffer, NULL);
536 return_try_again(r);
537 return_if_error(r, "keystore read_finish failed");
538
539 /* If json objects can't be parse the object store is corrupted */
540 jso = json_tokener_parse((char *)buffer);
541 SAFE_FREE(buffer);
542 return_if_null(jso, "Keystore is corrupted (Json error).", TSS2_FAPI_RC_GENERAL_FAILURE);
543
544 r = ifapi_json_IFAPI_OBJECT_deserialize(jso, object);
545 goto_if_error(r, "Deserialize object.", cleanup);
546
547 cleanup:
548 SAFE_FREE(buffer);
549 if (jso)
550 json_object_put(jso);
551 LOG_TRACE("Return %x", r);
552 return r;
553
554 }
555
556 /** Start writing FAPI object to the key store.
557 *
558 * Keys objects, NV objects, and hierarchies can be written.
559 *
560 * @param[in] keystore The key directories and default profile.
561 * @param[in] io The input/output context being used for file I/O.
562 * @param[in] path The relative path of the object. For keys the path will
563 * expanded if possible.
564 * @param[in] object The object to be written to the keystore.
565 * @retval TSS2_RC_SUCCESS if the object is written successfully.
566 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered;
567 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the output data.
568 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
569 * the function.
570 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
571 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
572 */
573 TSS2_RC
574 ifapi_keystore_store_async(
575 IFAPI_KEYSTORE *keystore,
576 IFAPI_IO *io,
577 const char *path,
578 const IFAPI_OBJECT *object)
579 {
580 TSS2_RC r;
581 char *directory = NULL;
582 char *file = NULL;
583 char *jso_string = NULL;
584 json_object *jso = NULL;
585
586 LOG_TRACE("Store object: %s", path);
587
588 /* Prepare write operation: Create directories and valid object path */
589 r = expand_path(keystore, path, &directory);
590 goto_if_error(r, "Expand path", cleanup);
591
592 if (object->system) {
593 r = ifapi_create_dirs(keystore->systemdir, directory);
594 goto_if_error2(r, "Directory %s could not be created.", cleanup, directory);
595
596 r = expand_path_to_object(keystore, directory,
597 keystore->systemdir, &file);
598 } else {
599 r = ifapi_create_dirs(keystore->userdir, directory);
600 goto_if_error2(r, "Directory %s could not be created.", cleanup, directory);
601
602 r = expand_path_to_object(keystore, directory,
603 keystore->userdir, &file);
604 }
605 goto_if_error2(r, "Object path %s could not be created.", cleanup, directory);
606
607 /* Generate JSON string to be written to store */
608 r = ifapi_json_IFAPI_OBJECT_serialize(object, &jso);
609 goto_if_error2(r, "Object for %s could not be serialized.", cleanup, file);
610
611 jso_string = strdup(json_object_to_json_string_ext(jso,
612 JSON_C_TO_STRING_PRETTY));
613 goto_if_null2(jso_string, "Converting json to string", r, TSS2_FAPI_RC_MEMORY,
614 cleanup);
615
616 /* Start writing the json string to disk */
617 r = ifapi_io_write_async(io, file, (uint8_t *) jso_string, strlen(jso_string));
618 free(jso_string);
619 goto_if_error(r, "write_async failed", cleanup);
620
621 cleanup:
622 if (jso)
623 json_object_put(jso);
624 SAFE_FREE(directory);
625 SAFE_FREE(file);
626 return r;
627 }
628
629 /** Finish writing a FAPI object to the keystore.
630 *
631 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
632 *
633 * @param[in] keystore The key directories and default profile.
634 * @param[in,out] io The input/output context being used for file I/O.
635 * @retval TSS2_RC_SUCCESS: if the function call was a success.
636 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
637 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
638 * Call this function again later.
639 */
640 TSS2_RC
641 ifapi_keystore_store_finish(
642 IFAPI_KEYSTORE *keystore,
643 IFAPI_IO *io)
644 {
645 TSS2_RC r;
646
647 /* Keystore parameter is used to be prepared if transmission of state information
648 between async and finish will be necessary in future extensions. */
649 (void)keystore;
650 /* Finish writing the object */
651 r = ifapi_io_write_finish(io);
652 return_try_again(r);
653
654 LOG_TRACE("Return %x", r);
655 return_if_error(r, "read_finish failed");
656
657 return TSS2_RC_SUCCESS;
658 }
659
660 /** Create a list of all files in a certain directory.
661 *
662 * The list will be created in form of absolute pathnames.
663 *
664 * @param[in] keystore The key directories and default profile.
665 * @param[in] searchpath The sub directory in key store used for the
666 * creation of the file list.
667 * @param[out] results The array of all absolute pathnames.
668 * @param[out] numresults The number of files.
669 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
670 */
671 static TSS2_RC
672 keystore_list_all_abs(
673 IFAPI_KEYSTORE *keystore,
674 const char *searchpath,
675 char ***results,
676 size_t *numresults)
677 {
678 TSS2_RC r;
679 char *expanded_search_path = NULL, *full_search_path = NULL;
680 size_t num_paths_system, num_paths_user, i, j;
681 char **file_ary, **file_ary_system, **file_ary_user;
682
683 *numresults = 0;
684 file_ary_user = NULL;
685 file_ary_system = NULL;
686
687 if (!searchpath || strcmp(searchpath, "") == 0 || strcmp(searchpath, "/") == 0) {
688 /* The complete keystore will be listed, no path expansion */
689 expanded_search_path = NULL;
690 } else {
691 r = expand_path(keystore, searchpath, &expanded_search_path);
692 return_if_error(r, "Out of memory.");
693 }
694
695 /* Get the objects from system store */
696 r = ifapi_asprintf(&full_search_path, "%s%s%s", keystore->systemdir, IFAPI_FILE_DELIM,
697 expanded_search_path ? expanded_search_path : "");
698 goto_if_error(r, "Out of memory.", cleanup);
699
700 r = ifapi_io_dirfiles_all(full_search_path, &file_ary_system, &num_paths_system);
701 goto_if_error(r, "Get all files in directory.", cleanup);
702 SAFE_FREE(full_search_path);
703
704 /* Get the objects from user store */
705 r = ifapi_asprintf(&full_search_path, "%s%s%s", keystore->userdir, IFAPI_FILE_DELIM,
706 expanded_search_path ? expanded_search_path : "");
707 goto_if_error(r, "Out of memory.", cleanup);
708
709 r = ifapi_io_dirfiles_all(full_search_path, &file_ary_user, &num_paths_user);
710
711 *numresults = num_paths_system + num_paths_user;
712 SAFE_FREE(full_search_path);
713
714 if (*numresults > 0) {
715
716 /* Move file names from list to combined array */
717 file_ary = calloc(*numresults, sizeof(char *));
718 goto_if_null(file_ary, "Out of memory.", TSS2_FAPI_RC_MEMORY,
719 cleanup);
720 i = 0;
721 for (j = 0; j < num_paths_system; j++)
722 file_ary[i++] = file_ary_system[j];
723 for (j = 0; j < num_paths_user; j++)
724 file_ary[i++] = file_ary_user[j];
725
726 SAFE_FREE(file_ary_system);
727 SAFE_FREE(file_ary_user);
728 SAFE_FREE(expanded_search_path);
729 *results = file_ary;
730 }
731
732 cleanup:
733 SAFE_FREE(file_ary_system);
734 SAFE_FREE(file_ary_user);
735 SAFE_FREE(expanded_search_path);
736 SAFE_FREE(full_search_path);
737 return r;
738 }
739
740 /** Create a list of of objects in a certain search path.
741 *
742 * A vector of relative paths will be computed.
743 *
744 * @param[in] keystore The key directories, the default profile.
745 * @param[in] searchpath The relative search path in key store.
746 * @param[out] results The array with pointers to the relative object paths.
747 * @param[out] numresults The number of found objects.
748 * @retval TSS2_RC_SUCCESS on success.
749 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
750 */
751 TSS2_RC
752 ifapi_keystore_list_all(
753 IFAPI_KEYSTORE *keystore,
754 const char *searchpath,
755 char ***results,
756 size_t *numresults)
757 {
758 TSS2_RC r;
759 size_t i;
760
761 r = keystore_list_all_abs(keystore, searchpath, results, numresults);
762 return_if_error(r, "Get all keystore objects.");
763
764 if (*numresults > 0) {
765 /* Convert absolute path to relative path */
766 for (i = 0; i < *numresults; i++) {
767 full_path_to_fapi_path(keystore, (*results)[i]);
768 }
769 }
770 return r;
771 }
772
773 /** Remove file storing a keystore object.
774 *
775 * @param[in] keystore The key directories, the default profile.
776 * @param[in] path The relative name of the object be removed.
777 * @retval TSS2_RC_SUCCESS On success.
778 * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated.
779 * @retval TSS2_FAPI_RC_IO_ERROR If the file can't be removed.
780 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
781 * during authorization.
782 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
783 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
784 * the function.
785 */
786 TSS2_RC
787 ifapi_keystore_delete(
788 IFAPI_KEYSTORE * keystore,
789 char *path)
790 {
791 TSS2_RC r;
792 char *abs_path = NULL;
793
794 /* Convert relative path to absolute path in keystore */
795 r = rel_path_to_abs_path(keystore, path, &abs_path);
796 goto_if_error2(r, "Object %s not found.", cleanup, path);
797
798 r = ifapi_io_remove_file(abs_path);
799
800 cleanup:
801 SAFE_FREE(abs_path);
802 return r;
803 }
804
805 /** Expand directory name.
806 *
807 * Depending on the directory type the path will be expanded. For hierarchies
808 * the profile directory will be added. For keys the implicit path will
809 * be expanded to an explicit path with all directories.
810 * @param[in] keystore The key directories and default profile.
811 * @param[in] path the implicit path which has to be expanded if possible.
812 * @param[out] directory_name The explicit path (callee-allocated)
813 * @retval TSS2_RC_SUCCESS If the explicit path was created.
814 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
815 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
816 * implicit path.
817 */
818 static TSS2_RC
819 expand_directory(IFAPI_KEYSTORE *keystore, const char *path, char **directory_name)
820 {
821 TSS2_RC r;
822
823 if (path && strcmp(path, "") != 0 && strcmp(path, "/") != 0) {
824 size_t start_pos = 0;
825 if (path[0] == IFAPI_FILE_DELIM_CHAR)
826 start_pos = 1;
827 if ((strncmp(&path[start_pos], "HS", 2) == 0 ||
828 strncmp(&path[start_pos], "HE", 2) == 0) &&
829 strlen(&path[start_pos]) <= 3) {
830 /* Root directory is hierarchy */
831 r = ifapi_asprintf(directory_name, "%s/", keystore->defaultprofile,
832 path[start_pos]);
833 return_if_error(r, "Out of memory.");
834
835 } else {
836 /* Try to expand a key path */
837 r = expand_path(keystore, path, directory_name);
838 return_if_error(r, "Out of memory.");
839 }
840 } else {
841 *directory_name = NULL;
842 }
843 return TSS2_RC_SUCCESS;
844 }
845
846 /** Remove directories in keystore.
847 *
848 * If the expanded directory exists in userdir and systemdir both will be deleted.
849 *
850 * @param[in] keystore The key directories, the default profile.
851 * @param[in] dir_name The relative name of the directory to be removed.
852 * @retval TSS2_RC_SUCCESS on success.
853 * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated.
854 * @retval TSS2_FAPI_RC_IO_ERROR If directory can't be deleted.
855 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
856 * the function.
857 */
858 TSS2_RC
859 ifapi_keystore_remove_directories(IFAPI_KEYSTORE *keystore, const char *dir_name)
860 {
861 TSS2_RC r = TSS2_RC_SUCCESS;
862 char *absolute_dir_path = NULL;
863 char *exp_dir_name = NULL;
864 struct stat fbuffer;
865
866 r = expand_directory(keystore, dir_name, &exp_dir_name);
867 return_if_error(r, "Expand path string.");
868
869 /* Cleanup user part of the store */
870 r = ifapi_asprintf(&absolute_dir_path, "%s%s%s", keystore->userdir, IFAPI_FILE_DELIM,
871 exp_dir_name ? exp_dir_name : "");
872 goto_if_error(r, "Out of memory.", cleanup);
873
874 if (stat(absolute_dir_path, &fbuffer) == 0) {
875 r = ifapi_io_remove_directories(absolute_dir_path);
876 goto_if_error2(r, "Could not remove: %s", cleanup, absolute_dir_path);
877 }
878 SAFE_FREE(absolute_dir_path);
879
880 /* Cleanup system part of the store */
881 r = ifapi_asprintf(&absolute_dir_path, "%s%s%s", keystore->systemdir,
882 IFAPI_FILE_DELIM, exp_dir_name ? exp_dir_name : "");
883 goto_if_error(r, "Out of memory.", cleanup);
884
885 if (stat(absolute_dir_path, &fbuffer) == 0) {
886 r = ifapi_io_remove_directories(absolute_dir_path);
887 goto_if_error2(r, "Could not remove: %s", cleanup, absolute_dir_path);
888 }
889
890 cleanup:
891 SAFE_FREE(absolute_dir_path);
892 SAFE_FREE(exp_dir_name);
893 return r;
894 }
895
896 /** Predicate used as function parameter for object searching in keystore.
897 *
898 * @param[in] object The object from keystore which has to be compared.
899 * @param[in] cmp_object The object which will used for the comparison,
900 * by the function with this signature.
901 * @retval true if the comparison is successful.
902 * @retval true if the comparison is not successful.
903 */
904 typedef TSS2_RC (*ifapi_keystore_object_cmp) (
905 IFAPI_OBJECT *object,
906 void *cmp_object,
907 bool *equal);
908
909 /** Search object with a certain propoerty in keystore.
910 *
911 * @param[in,out] keystore The key directories, the default profile, and the
912 * state information for the asynchronous search.
913 * @param[in] io The input/output context being used for file I/O.
914 * @param[in] name The name of the searched key.
915 * @param[out] found_path The relative path of the found key.
916 * @retval TSS2_RC_SUCCESS on success.
917 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
918 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND If the key was not found in keystore.
919 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
920 * during authorization.
921 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
922 * this function needs to be called again.
923 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
924 * operation already pending.
925 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
926 * the function.
927 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
928 * object store.
929 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
930 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
931 */
932 static TSS2_RC
933 keystore_search_obj(
934 IFAPI_KEYSTORE *keystore,
935 IFAPI_IO *io,
936 void *cmp_object,
937 ifapi_keystore_object_cmp cmp_function,
938 char **found_path)
939 {
940 TSS2_RC r;
941 UINT32 path_idx;
942 char *path;
943 IFAPI_OBJECT object;
944 size_t i;
945
946 switch (keystore->key_search.state) {
947 statecase(keystore->key_search.state, KSEARCH_INIT)
948 r = ifapi_keystore_list_all(keystore,
949 "/", /**< search keys and NV objects in store */
950 &keystore->key_search.pathlist,
951 &keystore->key_search.numPaths);
952 goto_if_error2(r, "Get entities.", cleanup);
953
954 keystore->key_search.path_idx = keystore->key_search.numPaths;
955 fallthrough;
956
957 statecase(keystore->key_search.state, KSEARCH_SEARCH_OBJECT)
958 /* Use the next object in the path list */
959 if (keystore->key_search.path_idx == 0) {
960 goto_error(r, TSS2_FAPI_RC_PATH_NOT_FOUND, "Key not found.", cleanup);
961 }
962 keystore->key_search.path_idx -= 1;
963 path_idx = keystore->key_search.path_idx;
964 path = keystore->key_search.pathlist[path_idx];
965 LOG_TRACE("Check file: %s %zu", path, keystore->key_search.path_idx);
966
967 r = ifapi_keystore_load_async(keystore, io, path);
968 return_if_error2(r, "Could not open: %s", path);
969
970 fallthrough;
971
972 statecase(keystore->key_search.state, KSEARCH_READ)
973 r = ifapi_keystore_load_finish(keystore, io, &object);
974 return_try_again(r);
975 goto_if_error(r, "read_finish failed", cleanup);
976
977 /* Check whether the key has the passed name */
978 bool keys_equal;
979 r = cmp_function(&object, cmp_object, &keys_equal);
980 ifapi_cleanup_ifapi_object(&object);
981 goto_if_error(r, "Invalid object.", cleanup);
982
983 if (!keys_equal) {
984 /* Try next key */
985 keystore->key_search.state = KSEARCH_SEARCH_OBJECT;
986 return TSS2_FAPI_RC_TRY_AGAIN;
987 }
988 /* Key found, the absolute path will be converted to relative path. */
989 path_idx = keystore->key_search.path_idx;
990 *found_path = strdup(keystore->key_search.pathlist[path_idx]);
991 goto_if_null(*found_path, "Out of memory.",
992 TSS2_FAPI_RC_MEMORY, cleanup);
993 full_path_to_fapi_path(keystore, *found_path);
994 break;
995
996 statecasedefault(keystore->key_search.state);
997 }
998 cleanup:
999 for (i = 0; i < keystore->key_search.numPaths; i++)
1000 free(keystore->key_search.pathlist[i]);
1001 free(keystore->key_search.pathlist);
1002 if (!*found_path) {
1003 LOG_ERROR("Object not found");
1004 r = TSS2_FAPI_RC_KEY_NOT_FOUND;
1005 }
1006 keystore->key_search.state = KSEARCH_INIT;
1007 return r;
1008 }
1009
1010 /** Search object with a certain name in keystore.
1011 *
1012 * @param[in,out] keystore The key directories, the default profile, and the
1013 * state information for the asynchronous search.
1014 * @param[in] io The input/output context being used for file I/O.
1015 * @param[in] name The name of the searched object.
1016 * @param[out] found_path The relative path of the found key.
1017 * @retval TSS2_RC_SUCCESS on success.
1018 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
1019 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND If the key was not found in keystore.
1020 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1021 * during authorization.
1022 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1023 * this function needs to be called again.
1024 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1025 * operation already pending.
1026 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1027 * the function.
1028 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1029 * object store.
1030 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1031 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1032 */
1033 TSS2_RC
1034 ifapi_keystore_search_obj(
1035 IFAPI_KEYSTORE *keystore,
1036 IFAPI_IO *io,
1037 TPM2B_NAME *name,
1038 char **found_path)
1039 {
1040 return keystore_search_obj(keystore, io, name,
1041 ifapi_object_cmp_name, found_path);
1042 }
1043
1044 /** Search nv object with a certain nv_index (from nv_public) in keystore.
1045 *
1046 * @param[in,out] keystore The key directories, the default profile, and the
1047 * state information for the asynchronous search.
1048 * @param[in] io The input/output context being used for file I/O.
1049 * @param[in] nv_public The public data of the searched nv object.
1050 * @param[out] found_path The relative path of the found key.
1051 * @retval TSS2_RC_SUCCESS on success.
1052 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
1053 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND If the key was not found in keystore.
1054 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1055 * the function.
1056 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1057 * during authorization.
1058 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1059 * this function needs to be called again.
1060 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1061 * operation already pending.
1062 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1063 * object store.
1064 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1065 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1066 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the object already exists in object store.
1067 */
1068 TSS2_RC
1069 ifapi_keystore_search_nv_obj(
1070 IFAPI_KEYSTORE *keystore,
1071 IFAPI_IO *io,
1072 TPM2B_NV_PUBLIC *nv_public,
1073 char **found_path)
1074 {
1075 return keystore_search_obj(keystore, io, nv_public,
1076 ifapi_object_cmp_nv_public, found_path);
1077 }
1078
1079 /** Check whether keystore object already exists.
1080 *
1081 * The passed relative path will be expanded for user store and system store.
1082 *
1083 * Keys objects, NV objects, and hierarchies can be written.
1084 *
1085 * @param[in] keystore The key directories and default profile.
1086 * @param[in] io The input/output context being used for file I/O.
1087 * @param[in] path The relative path of the object. For keys the path will
1088 * expanded if possible.
1089 * @retval TSS2_RC_SUCCESS if the object does not exist.
1090 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the file in objects exists.
1091 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the output data.
1092 */
1093 TSS2_RC
1094 ifapi_keystore_check_overwrite(
1095 IFAPI_KEYSTORE *keystore,
1096 IFAPI_IO *io,
1097 const char *path)
1098 {
1099 TSS2_RC r;
1100 char *directory = NULL;
1101 char *file = NULL;
1102 (void)io; /* Used to simplify future extensions */
1103
1104 /* Expand relative path */
1105 r = expand_path(keystore, path, &directory);
1106 goto_if_error(r, "Expand path", cleanup);
1107
1108 /* Expand absolute path for user and system directory */
1109 r = expand_path_to_object(keystore, directory,
1110 keystore->systemdir, &file);
1111 goto_if_error(r, "Expand path to object", cleanup);
1112
1113 if (ifapi_io_path_exists(file)) {
1114 goto_error(r, TSS2_FAPI_RC_PATH_ALREADY_EXISTS,
1115 "Object %s already exists.", cleanup, path);
1116 }
1117 SAFE_FREE(file);
1118 r = expand_path_to_object(keystore, directory,
1119 keystore->userdir, &file);
1120 goto_if_error(r, "Expand path to object", cleanup);
1121
1122 if (ifapi_io_path_exists(file)) {
1123 goto_error(r, TSS2_FAPI_RC_PATH_ALREADY_EXISTS,
1124 "Object %s already exists.", cleanup, path);
1125 }
1126 r = TSS2_RC_SUCCESS;
1127
1128 cleanup:
1129 SAFE_FREE(directory);
1130 SAFE_FREE(file);
1131 return r;
1132 }
1133
1134 /** Check whether keystore object is writeable.
1135 *
1136 * The passed relative path will be expanded first for user store, second for
1137 * system store if the file does not exist in system store.
1138 *
1139 * Keys objects, NV objects, and hierarchies can be written.
1140 *
1141 * @param[in] keystore The key directories and default profile.
1142 * @param[in] io The input/output context being used for file I/O.
1143 * @param[in] path The relative path of the object. For keys the path will
1144 * expanded if possible.
1145 * @retval TSS2_RC_SUCCESS if the object does not exist.
1146 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the file in objects exists.
1147 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the output data.
1148 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1149 * the function.
1150 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1151 * object store.
1152 */
1153 TSS2_RC
1154 ifapi_keystore_check_writeable(
1155 IFAPI_KEYSTORE *keystore,
1156 IFAPI_IO *io,
1157 const char *path)
1158 {
1159 TSS2_RC r;
1160 char *directory = NULL;
1161 char *file = NULL;
1162 (void)io; /* Used to simplify future extensions */
1163
1164 /* Expand relative path */
1165 r = expand_path(keystore, path, &directory);
1166 goto_if_error(r, "Expand path", cleanup);
1167
1168 /* Expand absolute path for user and system directory */
1169 r = expand_path_to_object(keystore, directory,
1170 keystore->userdir, &file);
1171 goto_if_error(r, "Expand path to object", cleanup);
1172
1173 if (ifapi_io_path_exists(file)) {
1174 r = ifapi_io_check_file_writeable(file);
1175 goto_if_error2(r, "Object %s is not writable.", cleanup, path);
1176
1177 /* File can be written */
1178 goto cleanup;
1179 } else {
1180 SAFE_FREE(file);
1181 r = expand_path_to_object(keystore, directory,
1182 keystore->systemdir, &file);
1183 goto_if_error(r, "Expand path to object", cleanup);
1184
1185 if (ifapi_io_path_exists(file)) {
1186 r = ifapi_io_check_file_writeable(file);
1187 goto_if_error2(r, "Object %s is not writable.", cleanup, path);
1188
1189 /* File can be written */
1190 goto cleanup;
1191 }
1192 }
1193
1194 cleanup:
1195 SAFE_FREE(directory);
1196 SAFE_FREE(file);
1197 return r;
1198 }
1199
1200 /** Create a copy of a an UINT8 array..
1201 *
1202 * @param[out] dest The caller allocated array which will be the
1203 * destination of the copy operation.
1204 * @param[in] src The source array.
1205 *
1206 * @retval TSS2_RC_SUCCESS if the function call was a success.
1207 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1208 */
1209 static TSS2_RC
1210 copy_uint8_ary(UINT8_ARY *dest, const UINT8_ARY * src) {
1211 TSS2_RC r = TSS2_RC_SUCCESS;
1212
1213 /* Check the parameters if they are valid */
1214 if (src == NULL || dest == NULL) {
1215 return TSS2_FAPI_RC_BAD_REFERENCE;
1216 }
1217
1218 /* Initialize the object variables for a possible error cleanup */
1219 dest->buffer = NULL;
1220
1221 /* Create the copy */
1222 dest->size = src->size;
1223 dest->buffer = malloc(dest->size);
1224 goto_if_null(dest->buffer, "Out of memory.", r, error_cleanup);
1225 memcpy(dest->buffer, src->buffer, dest->size);
1226
1227 return r;
1228
1229 error_cleanup:
1230 SAFE_FREE(dest->buffer);
1231 return r;
1232 }
1233
1234 /** Create a copy of a an ifapi key.
1235 *
1236 * @param[out] dest The caller allocated key object which will be the
1237 * destination of the copy operation.
1238 * @param[in] src The source key.
1239 *
1240 * @retval TSS2_RC_SUCCESS if the function call was a success.
1241 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1242 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1243 */
1244 TSS2_RC
1245 ifapi_copy_ifapi_key(IFAPI_KEY * dest, const IFAPI_KEY * src) {
1246 TSS2_RC r = TSS2_RC_SUCCESS;
1247
1248 /* Check the parameters if they are valid */
1249 if (src == NULL || dest == NULL) {
1250 return TSS2_FAPI_RC_BAD_REFERENCE;
1251 }
1252
1253 /* Initialize the object variables for a possible error cleanup */
1254 dest->private.buffer = NULL;
1255 dest->serialization.buffer = NULL;
1256 dest->appData.buffer = NULL;
1257 dest->policyInstance = NULL;
1258 dest->description = NULL;
1259
1260 /* Create the copy */
1261
1262 r = copy_uint8_ary(&dest->private, &src->private);
1263 goto_if_error(r, "Could not copy private", error_cleanup);
1264 r = copy_uint8_ary(&dest->serialization, &src->serialization);
1265 goto_if_error(r, "Could not copy serialization", error_cleanup);
1266 r = copy_uint8_ary(&dest->appData, &src->appData);
1267 goto_if_error(r, "Could not copy appData", error_cleanup);
1268
1269 strdup_check(dest->policyInstance, src->policyInstance, r, error_cleanup);
1270 strdup_check(dest->description, src->description, r, error_cleanup);
1271 strdup_check(dest->certificate, src->certificate, r, error_cleanup);
1272
1273 dest->persistent_handle = src->persistent_handle;
1274 dest->public = src->public;
1275 dest->creationData = src->creationData;
1276 dest->creationTicket = src->creationTicket;
1277 dest->signing_scheme = src->signing_scheme;
1278 dest->name = src->name;
1279 dest->with_auth = src->with_auth;
1280
1281 return r;
1282
1283 error_cleanup:
1284 ifapi_cleanup_ifapi_key(dest);
1285 return r;
1286 }
1287
1288 /** Free memory allocated during deserialization of a key object.
1289 *
1290 * The key will not be freed (might be declared on the stack).
1291 *
1292 * @param[in] key The key object to be cleaned up.
1293 *
1294 */
1295 void
1296 ifapi_cleanup_ifapi_key(IFAPI_KEY * key) {
1297 if (key != NULL) {
1298 SAFE_FREE(key->policyInstance);
1299 SAFE_FREE(key->serialization.buffer);
1300 SAFE_FREE(key->private.buffer);
1301 SAFE_FREE(key->description);
1302 SAFE_FREE(key->certificate);
1303 SAFE_FREE(key->appData.buffer);
1304 }
1305 }
1306
1307 /** Free memory allocated during deserialization of a pubkey object.
1308 *
1309 * The pubkey will not be freed (might be declared on the stack).
1310 *
1311 * @param[in] key The pubkey object to be cleaned up.
1312 */
1313 void
1314 ifapi_cleanup_ifapi_ext_pub_key(IFAPI_EXT_PUB_KEY * key) {
1315 if (key != NULL) {
1316 SAFE_FREE(key->pem_ext_public);
1317 SAFE_FREE(key->certificate);
1318 }
1319 }
1320
1321 /** Free memory allocated during deserialization of a hierarchy object.
1322 *
1323 * The hierarchy object will not be freed (might be declared on the stack).
1324 *
1325 * @param[in] hierarchy The hierarchy object to be cleaned up.
1326 */
1327 void
1328 ifapi_cleanup_ifapi_hierarchy(IFAPI_HIERARCHY * hierarchy) {
1329 if (hierarchy != NULL) {
1330 SAFE_FREE(hierarchy->description);
1331 }
1332 }
1333
1334 /** Free memory allocated during deserialization of a nv object.
1335 *
1336 * The nv object will not be freed (might be declared on the stack).
1337 *
1338 * @param[in] nv The nv object to be cleaned up.
1339 */
1340 void
1341 ifapi_cleanup_ifapi_nv(IFAPI_NV * nv) {
1342 if (nv != NULL) {
1343 SAFE_FREE(nv->serialization.buffer);
1344 SAFE_FREE(nv->appData.buffer);
1345 SAFE_FREE(nv->policyInstance);
1346 SAFE_FREE(nv->description);
1347 SAFE_FREE(nv->event_log);
1348 }
1349 }
1350
1351 /** Free memory allocated during deserialization of a duplicate object.
1352 *
1353 * The duplicate object will not be freed (might be declared on the stack).
1354 *
1355 * @param[in] duplicate The duplicate object to be cleaned up.
1356 */
1357 void
1358 ifapi_cleanup_ifapi_duplicate(IFAPI_DUPLICATE * duplicate) {
1359 if (duplicate != NULL) {
1360 SAFE_FREE(duplicate->certificate);
1361 }
1362 }
1363
1364 /** Free keystore related memory allocated during FAPI initialization.
1365 *
1366 * The keystore object will not be freed (might be declared on the stack).
1367 *
1368 * @param[in] keystore The kystore object to be cleaned up.
1369 */
1370 void
1371 ifapi_cleanup_ifapi_keystore(IFAPI_KEYSTORE * keystore) {
1372 if (keystore != NULL) {
1373 SAFE_FREE(keystore->systemdir);
1374 SAFE_FREE(keystore->userdir);
1375 SAFE_FREE(keystore->defaultprofile);
1376 }
1377 }
1378
1379 /** Create a copy of a an ifapi object storing a key.
1380 *
1381 * The key together with the policy of the key will be copied.
1382 *
1383 * @param[out] dest The caller allocated key object which will be the
1384 * destination of the copy operation.
1385 * @param[in] src The source key.
1386 *
1387 * @retval TSS2_RC_SUCCESS if the function call was a success.
1388 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if the source is not of type key.
1389 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1390 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1391 */
1392 TSS2_RC
1393 ifapi_copy_ifapi_key_object(IFAPI_OBJECT * dest, const IFAPI_OBJECT * src) {
1394 TSS2_RC r = TSS2_RC_SUCCESS;
1395
1396 /* Check the parameters if they are valid */
1397 if (src == NULL || dest == NULL) {
1398 return TSS2_FAPI_RC_BAD_REFERENCE;
1399 }
1400
1401 if (src->objectType != IFAPI_KEY_OBJ) {
1402 LOG_ERROR("Bad object type");
1403 return TSS2_FAPI_RC_GENERAL_FAILURE;
1404 }
1405
1406 /* Initialize the object variables for a possible error cleanup */
1407
1408 /* Create the copy */
1409 dest->policy = ifapi_copy_policy(src->policy);
1410
1411 ifapi_copy_ifapi_key(&dest->misc.key, &src->misc.key);
1412 goto_if_error(r, "Could not copy key", error_cleanup);
1413
1414 dest->objectType = src->objectType;
1415 dest->system = src->system;
1416 dest->handle = src->handle;
1417 dest->authorization_state = src->authorization_state;
1418
1419 return r;
1420
1421 error_cleanup:
1422 ifapi_cleanup_ifapi_object(dest);
1423 return r;
1424 }
1425
1426 /** Free memory allocated during deserialization of object.
1427 *
1428 * The object will not be freed (might be declared on the stack).
1429 *
1430 * @param[in] object The object to be cleaned up.
1431 *
1432 */
1433 void
1434 ifapi_cleanup_ifapi_object(
1435 IFAPI_OBJECT * object)
1436 {
1437 if (object != NULL) {
1438 if (object->objectType != IFAPI_OBJ_NONE) {
1439 if (object->objectType == IFAPI_KEY_OBJ) {
1440 ifapi_cleanup_ifapi_key(&object->misc.key);
1441 } else if (object->objectType == IFAPI_NV_OBJ) {
1442 ifapi_cleanup_ifapi_nv(&object->misc.nv);
1443 } else if (object->objectType == IFAPI_DUPLICATE_OBJ) {
1444 ifapi_cleanup_ifapi_duplicate(&object->misc.key_tree);
1445 } else if (object->objectType == IFAPI_EXT_PUB_KEY_OBJ) {
1446 ifapi_cleanup_ifapi_ext_pub_key(&object->misc.ext_pub_key);
1447 } else if (object->objectType == IFAPI_HIERARCHY_OBJ) {
1448 ifapi_cleanup_ifapi_hierarchy(&object->misc.hierarchy);
1449 }
1450
1451 ifapi_cleanup_policy(object->policy);
1452 SAFE_FREE(object->policy);
1453 object->objectType = IFAPI_OBJ_NONE;
1454 }
1455 }
1456 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifndef IFAPI_KEYSTORE_H
7 #define IFAPI_KEYSTORE_H
8
9 #include <stdlib.h>
10
11 #include "tss2_common.h"
12 #include "tss2_tpm2_types.h"
13 #include "fapi_types.h"
14 #include "ifapi_policy_types.h"
15 #include "tss2_esys.h"
16
17 typedef UINT32 IFAPI_OBJECT_TYPE_CONSTANT;
18 #define IFAPI_OBJ_NONE 0 /**< Tag for key resource */
19 #define IFAPI_KEY_OBJ 1 /**< Tag for key resource */
20 #define IFAPI_NV_OBJ 2 /**< Tag for NV Ram resource */
21 #define IFAPI_EXT_PUB_KEY_OBJ 3 /**< Tag for key resource */
22 #define IFAPI_HIERARCHY_OBJ 4 /**< Tag for other resources, e.g. PCR register, hierarchies */
23 #define IFAPI_DUPLICATE_OBJ 5 /**< Tag for key duplication object */
24
25 /** Type for representing a FAPI key
26 */
27 typedef struct {
28 UINT32 persistent_handle; /**< Persistent TPM Handle */
29 TPM2B_PUBLIC public; /**< The wrapped public portion of the object */
30 UINT8_ARY serialization; /**< None */
31 UINT8_ARY private; /**< None */
32 char *policyInstance; /**< Keys policy */
33 TPM2B_CREATION_DATA creationData; /**< None */
34 TPMT_TK_CREATION creationTicket; /**< None */
35 char *description; /**< Human readable description of key */
36 UINT8_ARY appData; /**< Application data */
37 char *certificate; /**< Keys certificate (if any) */
38 TPMT_SIG_SCHEME signing_scheme; /**< Signing scheme for the key */
39 TPM2B_NAME name; /**< Name of the key */
40 TPMI_YES_NO with_auth; /**< Authorization provided during creation */
41 } IFAPI_KEY;
42
43 /** Type for representing a external public key
44 */
45 typedef struct {
46 char *pem_ext_public; /**< Public key in PEM format */
47 char *certificate; /**< Keys certificate (if any) */
48 TPM2B_PUBLIC public; /**< The pulic information in TPM format */
49 } IFAPI_EXT_PUB_KEY;
50
51 /** Type for representing hierarchy
52 */
53 typedef struct {
54 TPMI_YES_NO with_auth; /**< Authorization provided */
55 char *description; /**< Human readable description of hierarchy */
56 TPM2B_DIGEST authPolicy;
57 } IFAPI_HIERARCHY;
58
59 /** Type for representing a FAPI NV object
60 */
61 typedef struct {
62 TPM2B_NV_PUBLIC public; /**< The wrapped public portion of the object */
63 UINT8_ARY serialization; /**< None */
64 UINT32 hierarchy; /**< The hierarchy used for NV object creation */
65 char *policyInstance; /**< Keys policy */
66 char *description; /**< Human readable description of key */
67 UINT8_ARY appData; /**< Application data */
68 TPMI_YES_NO with_auth; /**< Authorization provided during creation */
69 char* event_log; /**< The event log if NV type is pcr */
70 } IFAPI_NV;
71
72 /** Type for representing a FAPI object for key duplication.
73 */
74 typedef struct {
75
76 TPM2B_PRIVATE duplicate; /**< The duplicate of the key to export*/
77 TPM2B_ENCRYPTED_SECRET encrypted_seed; /**< Encrypted seed needed for key import */
78 TPM2B_PUBLIC public; /**< The public information of the key to be duplicated */
79 TPM2B_PUBLIC public_parent; /**< The public information of the new parent key */
80 char *certificate; /**< The certificate of the key to be duplicated */
81 TPMS_POLICY *policy; /**< The policy of the key to be duplicated */
82 } IFAPI_DUPLICATE;
83
84 /** type for representing public info of a TPM-Resource
85 */
86 typedef union {
87 IFAPI_EXT_PUB_KEY ext_pub_key; /**< Public info for external key. */
88 IFAPI_KEY key; /**< Public info for key objects */
89 IFAPI_NV nv; /**< Public info for NV ram objects */
90 IFAPI_DUPLICATE key_tree; /**< Information for key duplication */
91 IFAPI_HIERARCHY hierarchy; /**< Information related to hierarchies */
92 } IFAPI_OBJECT_UNION;
93
94 /** The states for key searching */
95 enum FAPI_SEARCH_STATE {
96 KSEARCH_INIT = 0,
97 KSEARCH_SEARCH_OBJECT,
98 KSEARCH_READ
99 };
100
101 /** The data structure holding internal state for key searching.
102 */
103 typedef struct {
104 size_t path_idx; /**< Index of array of objects to be searched */
105 size_t numPaths; /**< Number of all objects in data store */
106 char **pathlist; /**< The array of all objects in the search path */
107 enum FAPI_SEARCH_STATE state;
108 } IFAPI_KEY_SEARCH;
109
110 typedef struct IFAPI_KEYSTORE {
111 char *systemdir;
112 char *userdir;
113 char *defaultprofile;
114 IFAPI_KEY_SEARCH key_search;
115 } IFAPI_KEYSTORE;
116
117
118 /** The states for the FAPI's object authorization state*/
119 enum IFAPI_AUTHORIZATION_STATE {
120 AUTH_INIT = 0,
121 AUTH_CHECK_POLICY,
122 AUTH_CREATE_SESSION,
123 AUTH_EXEC_POLICY,
124 AUTH_FLUSH_OLD_POLICY,
125 AUTH_DONE
126 };
127
128 /** The states for the FAPI's object write/read state*/
129 enum IFAPI_IO_STATE {
130 IO_INIT = 0,
131 IO_ACTIVE,
132 };
133
134 /** Type for representing TPM-Resource
135 */
136 typedef struct _IFAPI_OBJECT {
137 TPMS_POLICY *policy;
138 IFAPI_OBJECT_TYPE_CONSTANT objectType; /**< Selector for object type */
139 IFAPI_OBJECT_UNION misc; /**< Resource specific information */
140 TPMI_YES_NO system; /**< Store the object in the system wide
141 directory */
142 ESYS_TR handle; /**< Handle used by ESAPI */
143 enum IFAPI_AUTHORIZATION_STATE authorization_state; /**< State of object authorization state machine */
144 enum IFAPI_IO_STATE state;
145
146 } IFAPI_OBJECT;
147
148
149 TSS2_RC
150 ifapi_keystore_initialize(
151 IFAPI_KEYSTORE *keystore,
152 const char *config_systemdir,
153 const char *config_userdir,
154 const char *config_defaultprofile);
155
156 TSS2_RC
157 ifapi_keystore_load_async(
158 IFAPI_KEYSTORE *keystore,
159 IFAPI_IO *io,
160 const char *path);
161
162 TSS2_RC
163 ifapi_keystore_load_finish(
164 IFAPI_KEYSTORE *keystore,
165 IFAPI_IO *io,
166 IFAPI_OBJECT *object);
167
168 TSS2_RC
169 ifapi_keystore_store_async(
170 IFAPI_KEYSTORE *keystore,
171 IFAPI_IO *io,
172 const char *path,
173 const IFAPI_OBJECT *object);
174
175 TSS2_RC
176 ifapi_keystore_store_finish(
177 IFAPI_KEYSTORE *keystore,
178 IFAPI_IO *io);
179
180 TSS2_RC
181 ifapi_keystore_list_all(
182 IFAPI_KEYSTORE *keystore,
183 const char *searchpath,
184 char ***results,
185 size_t *numresults);
186
187 TSS2_RC
188 ifapi_keystore_delete(
189 IFAPI_KEYSTORE *keystore,
190 char *path);
191
192 TSS2_RC
193 ifapi_keystore_remove_directories(
194 IFAPI_KEYSTORE *keystore,
195 const char *dir_name);
196
197 TSS2_RC
198 ifapi_keystore_search_obj(
199 IFAPI_KEYSTORE *keystore,
200 IFAPI_IO *io,
201 TPM2B_NAME *name,
202 char **found_path);
203
204 TSS2_RC
205 ifapi_keystore_search_nv_obj(
206 IFAPI_KEYSTORE *keystore,
207 IFAPI_IO *io,
208 TPM2B_NV_PUBLIC *nv_public,
209 char **found_path);
210
211 TSS2_RC
212 ifapi_keystore_check_overwrite(
213 IFAPI_KEYSTORE *keystore,
214 IFAPI_IO *io,
215 const char *path);
216
217 TSS2_RC
218 ifapi_keystore_check_writeable(
219 IFAPI_KEYSTORE *keystore,
220 IFAPI_IO *io,
221 const char *path);
222
223 TSS2_RC
224 ifapi_copy_ifapi_key(
225 IFAPI_KEY * dest,
226 const IFAPI_KEY * src);
227
228 TSS2_RC
229 ifapi_copy_ifapi_key_object(
230 IFAPI_OBJECT * dest,
231 const IFAPI_OBJECT * src);
232
233 void ifapi_cleanup_ifapi_key(
234 IFAPI_KEY * key);
235
236 void ifapi_cleanup_ifapi_ext_pub_key(
237 IFAPI_EXT_PUB_KEY * key);
238
239 void ifapi_cleanup_ifapi_hierarchy(
240 IFAPI_HIERARCHY * hierarchy);
241
242 void ifapi_cleanup_ifapi_nv(
243 IFAPI_NV * nv);
244
245 void ifapi_cleanup_ifapi_duplicate(
246 IFAPI_DUPLICATE * duplicate);
247
248 void ifapi_cleanup_ifapi_key_search(
249 IFAPI_KEY_SEARCH * key_search);
250
251 void ifapi_cleanup_ifapi_keystore(
252 IFAPI_KEYSTORE * keystore);
253
254 void
255 ifapi_cleanup_ifapi_object(
256 IFAPI_OBJECT *object);
257
258 #endif /* IFAPI_KEYSTORE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef IFAPI_MACROS_H
6 #define IFAPI_MACROS_H
7
8 #define strdup_check(dest, str, r, label) \
9 if (str) { \
10 dest = strdup(str); \
11 if (!dest) { \
12 r = TSS2_FAPI_RC_MEMORY; \
13 LOG_ERROR("Out of memory."); \
14 goto label; \
15 } \
16 } else { \
17 dest = NULL; \
18 }
19
20 #define calloc_check(dest, size, r, label) \
21 { \
22 dest = callock(size,1); \
23 if (!dest) { \
24 r = TSS2_FAPI_RC_MEMORY; \
25 LOG_ERROR("Out of memory."); \
26 goto label; \
27 } \
28 }
29
30 #define goto_if_null2(p,msg, r, ec, label, ...) \
31 if ((p) == NULL) { \
32 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(ec), ## __VA_ARGS__); \
33 r = (ec); \
34 goto label; \
35 }
36
37 #define goto_if_error2(r,msg,label, ...) \
38 if (r != TSS2_RC_SUCCESS) { \
39 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
40 goto label; \
41 }
42
43 #define return_if_error2(r,msg, ...) \
44 if (r != TSS2_RC_SUCCESS) { \
45 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
46 return r; \
47 }
48
49 #define try_again_or_error(r,msg, ...) \
50 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) \
51 return TSS2_FAPI_RC_TRY_AGAIN; \
52 if (r != TSS2_RC_SUCCESS) { \
53 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
54 return r; \
55 }
56
57 #define try_again_or_error_goto(r,msg, label, ...) \
58 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) \
59 return TSS2_FAPI_RC_TRY_AGAIN; \
60 if (r != TSS2_RC_SUCCESS) { \
61 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
62 goto label; \
63 }
64
65 #define return_error2(r,msg, ...) { \
66 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
67 return (r); }
68
69
70 #define return_if_error_reset_state(r,msg, ...) \
71 if (r != TSS2_RC_SUCCESS) { \
72 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
73 context->state = _FAPI_STATE_INIT; \
74 return r; \
75 }
76
77 #define goto_if_error_reset_state(r,msg,label, ...) \
78 if (r != TSS2_RC_SUCCESS) { \
79 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
80 context->state = _FAPI_STATE_INIT; \
81 goto label; \
82 }
83
84 #define goto_error_reset_state(r,v,msg,label) { \
85 r = v; \
86 LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
87 context->state = _FAPI_STATE_INIT; \
88 goto label; }
89
90 #define goto_if_null_reset_state(p,msg,r,ec,label) \
91 if ((p) == NULL) { \
92 LOG_ERROR("%s ", (msg)); \
93 context->state = _FAPI_STATE_INIT; \
94 (r) = (ec); \
95 goto label; \
96 }
97
98 #define return_try_again(r) \
99 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) { \
100 LOG_TRACE("Received TRY_AGAIN; returning TRY_AGAIN"); \
101 return TSS2_FAPI_RC_TRY_AGAIN; \
102 }
103
104 #define check_not_null(X) \
105 if (X == NULL) { \
106 LOG_ERROR(str(X) " is NULL: BAD_REFERENCE"); \
107 return TSS2_FAPI_RC_BAD_REFERENCE; \
108 }
109
110 #define check_oom(X) \
111 if (X == NULL) { \
112 LOG_ERROR("Out of memory"); \
113 return TSS2_FAPI_RC_MEMORY; \
114 }
115
116 #if defined __GNUC__ && __GNUC__ < 7
117 #define fallthrough { }
118 #else
119 #define fallthrough __attribute__((fallthrough))
120 #endif
121
122 #define statecase(VAR, STATE) \
123 case STATE: \
124 LOG_TRACE("State " str(VAR) " reached " str(STATE)); \
125 VAR=STATE;
126
127 #define general_failure(VAR) \
128 default: \
129 LOG_ERROR("Bad state for " str(VAR)); \
130 return TSS2_FAPI_RC_GENERAL_FAILURE;
131
132 #define statecasedefault(VAR) \
133 default: \
134 LOG_ERROR("Bad state for " str(VAR)); \
135 return TSS2_FAPI_RC_BAD_SEQUENCE;
136
137 #define statecasedefault_error(VAR, r, label) \
138 default: \
139 LOG_ERROR("Bad state for " str(VAR)); \
140 r = TSS2_FAPI_RC_BAD_SEQUENCE; \
141 goto label;
142
143 #endif /* IFAPI_MACROS_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "tss2_mu.h"
14 #include "fapi_util.h"
15 #include "fapi_int.h"
16 #include "fapi_crypto.h"
17 #include "fapi_policy.h"
18 #include "ifapi_policy_instantiate.h"
19 #include "ifapi_policy_callbacks.h"
20 #include "ifapi_helpers.h"
21 #include "ifapi_json_deserialize.h"
22 #include "tpm_json_deserialize.h"
23 #include "ifapi_policy_store.h"
24 #define LOGMODULE fapi
25 #include "util/log.h"
26 #include "util/aux_util.h"
27
28 /** Compute policy digest for a policy tree.
29 *
30 * A policy or a policy path can be passed. If a policy is passed the
31 * policy is computed directly from the policy otherwise the policy has to be
32 * retrieved from policy store to determine the policy.
33 *
34 * @param[in,out] context The FAPI_CONTEXT.
35 * @param[in] policyPath The policy path for policy store.
36 * @param[in] policy The result of policy deserialization.
37 * @param[in] hash_alg The used hash alg for policy digest computations.
38 * @param[out] digest_idx The index of the current digest. The policy digest can be
39 * computed for several hash algorithms the digets index is a reverence
40 * to the current digest values.
41 * @param[out] hash_size The size of the current policy digest.
42 *
43 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
44 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
45 * not covered by other return codes.
46 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during policy calculation.
47 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
48 * store.
49 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If an object needed for policy calculation was
50 * not found.
51 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
52 * not successful.
53 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
54 * this function needs to be called again.
55 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
56 * operation already pending.
57 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
58 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
59 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
60 */
61 TSS2_RC
62 ifapi_calculate_tree(
63 FAPI_CONTEXT *context,
64 const char *policyPath,
65 TPMS_POLICY *policy,
66 TPMI_ALG_HASH hash_alg,
67 size_t *digest_idx,
68 size_t *hash_size)
69 {
70 size_t i;
71 TSS2_RC r = TSS2_RC_SUCCESS;
72 bool already_computed = false;
73 IFAPI_POLICY_EVAL_INST_CTX *eval_ctx = NULL;
74 ifapi_policyeval_INST_CB *callbacks;
75
76 if (context->policy.state == POLICY_INIT && !policyPath)
77 /* Skip policy reading */
78 context->policy.state = POLICY_INSTANTIATE_PREPARE;
79
80 switch (context->policy.state) {
81 statecase(context->policy.state, POLICY_INIT);
82 fallthrough;
83
84 statecase(context->policy.state, POLICY_READ);
85 r = ifapi_policy_store_load_async(&context->pstore, &context->io, policyPath);
86 goto_if_error2(r, "Can't open: %s", cleanup, policyPath);
87 fallthrough;
88
89 statecase(context->policy.state, POLICY_READ_FINISH);
90 r = ifapi_policy_store_load_finish(&context->pstore, &context->io, policy);
91 return_try_again(r);
92 return_if_error_reset_state(r, "read_finish failed");
93 fallthrough;
94
95 statecase(context->policy.state, POLICY_INSTANTIATE_PREPARE);
96 eval_ctx = &context->policy.eval_ctx;
97 callbacks = &eval_ctx->callbacks;
98 callbacks->cbname = ifapi_get_object_name;
99 callbacks->cbname_userdata = context;
100 callbacks->cbpublic = ifapi_get_key_public;
101 callbacks->cbpublic_userdata = context;
102 callbacks->cbnvpublic = ifapi_get_nv_public;
103 callbacks->cbnvpublic_userdata = context;
104 callbacks->cbpcr = ifapi_read_pcr;
105 callbacks->cbpcr_userdata = context;
106
107 r = ifapi_policyeval_instantiate_async(eval_ctx, policy, callbacks);
108 goto_if_error(r, "Instantiate policy.", cleanup);
109 fallthrough;
110
111 statecase(context->policy.state, POLICY_INSTANTIATE);
112 r = ifapi_policyeval_instantiate_finish(&context->policy.eval_ctx);
113 FAPI_SYNC(r, "Instantiate policy.", cleanup);
114 ifapi_free_node_list(context->policy.eval_ctx.policy_elements);
115 if (!(*hash_size = ifapi_hash_get_digest_size(hash_alg))) {
116 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
117 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
118 hash_alg);
119 }
120
121 for (i = 0; i < policy->policyDigests.count; i++) {
122 if (policy->policyDigests.digests[i].hashAlg == hash_alg) {
123 /* Digest already computed */
124 *digest_idx = i;
125 already_computed = true;
126 }
127 }
128 if (already_computed)
129 break;
130
131 if (i > TPM2_NUM_PCR_BANKS) {
132 return_error(TSS2_FAPI_RC_BAD_VALUE, "Table overflow");
133 }
134 *digest_idx = i;
135 policy->policyDigests.count += 1;
136 policy->policyDigests.digests[i].hashAlg = hash_alg;
137
138 memset(&policy->policyDigests.digests[*digest_idx].digest, 0,
139 sizeof(TPMU_HA));
140
141 r = ifapi_calculate_policy(policy->policy,
142 &policy->policyDigests, hash_alg,
143 *hash_size, *digest_idx);
144 goto_if_error(r, "Compute policy.", cleanup);
145
146 break;
147 statecasedefault(context->policy.state);
148 }
149 cleanup:
150 context->policy.state = POLICY_INIT;
151 return r;
152 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef IFAPI_POLICY_H
6 #define IFAPI_POLICY_H
7
8 #include <stdint.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <json-c/json.h>
13 #include <json-c/json_util.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 #include "fapi_policy.h"
19
20 TSS2_RC
21 get_policy_digest_idx(
22 TPML_DIGEST_VALUES *digest_values,
23 TPMI_ALG_HASH hashAlg,
24 size_t *idx);
25
26 TSS2_RC
27 ifapi_compute_policy_digest(
28 TPML_PCRVALUES *pcrs,
29 TPML_PCR_SELECTION *pcr_selection,
30 TPMI_ALG_HASH hash_alg,
31 TPM2B_DIGEST *pcr_digest);
32
33 TSS2_RC
34 ifapi_calculate_tree(
35 FAPI_CONTEXT *context,
36 const char *policyPath,
37 TPMS_POLICY *policy,
38 TPMI_ALG_HASH hash_alg,
39 size_t *digest_idx,
40 size_t *hash_size);
41
42 #endif /* IFAPI_POLICY_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "tss2_mu.h"
14 #include "fapi_util.h"
15 #include "fapi_crypto.h"
16 #include "fapi_policy.h"
17 #include "ifapi_helpers.h"
18 #include "ifapi_json_deserialize.h"
19 #include "tpm_json_deserialize.h"
20 #define LOGMODULE fapi
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 /** Copy policy digest.
25 *
26 * One digest is copied from certain position in a policy list to the
27 * same position in a second list.
28 *
29 * @param[out] dest The digest list to which the new value is added.
30 * @param[in] src The digest list with the value to be copied.
31 * @param[in] digest_idx The index of the digest to be copied.
32 * @param[in] hash_size The number of bytes to be copied.
33 * @param[in] txt Text which will be used for additional logging information..
34 * @retval TSS2_RC_SUCCESS on success.
35 */
36 static void
37 copy_policy_digest(TPML_DIGEST_VALUES *dest, TPML_DIGEST_VALUES *src,
38 size_t digest_idx, size_t hash_size, char *txt)
39 {
40 memcpy(&dest->digests[digest_idx].digest, &src->digests[digest_idx].digest,
41 hash_size);
42 dest->digests[digest_idx].hashAlg = src->digests[digest_idx].hashAlg;
43 LOGBLOB_DEBUG((uint8_t *)&dest->digests[digest_idx].digest, hash_size,
44 "%s : Copy digest size: %zu", txt, hash_size);
45 dest->count = src->count;
46 }
47
48 /** Logdefault policy digest.
49 *
50 * @param[in] dest The digest to be logged.
51 * @param[in] digest_idx The index of the digest to be logged
52 * @param[in] hash_size The number of bytes to be logged
53 * @param[in] txt Text which will be used for additional logging information.
54 */
55 static void
56 log_policy_digest(TPML_DIGEST_VALUES *dest, size_t digest_idx, size_t hash_size,
57 char *txt)
58 {
59 LOGBLOB_DEBUG((uint8_t *)&dest->digests[digest_idx].digest, hash_size,
60 "Digest %s", txt);
61 }
62
63 /** Calculate a policy digest for a certain PCR selection.
64 *
65 * From a PCR list the list of PCR values and the corresponding PCR digest
66 * is computed. The passed policy digest will be extended with this data
67 * and also with the policy command code.
68 *
69 * @param[in] policy The policy with the list of selected PCRs.
70 * @param[in,out] current_digest The digest list which has to be updated.
71 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
72 *
73 * @retval TSS2_RC_SUCCESS on success.
74 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
75 * the function.
76 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
77 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
78 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
79 */
80 TSS2_RC
81 ifapi_compute_policy_pcr(
82 TPMS_POLICYPCR *policy,
83 TPML_DIGEST_VALUES *current_digest,
84 TPMI_ALG_HASH current_hash_alg)
85 {
86 TSS2_RC r = TSS2_RC_SUCCESS;
87 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
88 TPML_PCR_SELECTION pcr_selection;
89 size_t digest_idx;
90 TPM2B_DIGEST pcr_digest;
91 size_t hash_size;
92
93 LOG_TRACE("call");
94
95 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
96 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
97 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
98 current_hash_alg);
99 }
100
101 /* Compute of the index of the current policy in the passed digest list */
102 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
103 return_if_error(r, "Get hash alg for digest.");
104
105 /* Compute PCR selection and pcr digest */
106 r = ifapi_compute_policy_digest(policy->pcrs, &pcr_selection,
107 current_hash_alg, &pcr_digest);
108 return_if_error(r, "Compute policy digest and selection.");
109
110 LOG_TRACE("Compute policy pcr");
111 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
112 return_if_error(r, "crypto hash start");
113
114 /* Update the passed policy. */
115 HASH_UPDATE_BUFFER(cryptoContext,
116 &current_digest->digests[digest_idx].digest, hash_size,
117 r, cleanup);
118 HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyPCR, r, cleanup);
119 /* The marshaled version of the digest list will be added. */
120 HASH_UPDATE(cryptoContext, TPML_PCR_SELECTION, &pcr_selection, r, cleanup);
121 HASH_UPDATE_BUFFER(cryptoContext, &pcr_digest.buffer[0], hash_size, r,
122 cleanup);
123
124 r = ifapi_crypto_hash_finish(&cryptoContext,
125 (uint8_t *) & current_digest->
126 digests[digest_idx].digest, &hash_size);
127 return_if_error(r, "crypto hash finish");
128
129 cleanup:
130 if (cryptoContext)
131 ifapi_crypto_hash_abort(&cryptoContext);
132 return r;
133 }
134
135 /** Calculate a policy digest for a TPM2B object name, and a policy reference.
136 *
137 * A policy hash based on a passed policy digest, the policy command code,
138 * optionally the name, and the policy reference will be computed.
139 * The calculation is carried out in two steps. First a hash with the
140 * command code and the passed digest, and optionaly the name is computed.
141 * This digest, together with the other parameters is used to compute
142 * the final policy digest.
143 *
144 * @param[in] command_code The TPM command code of the policy command.
145 * @param[in] name The name of a key or a NV object.
146 * @param[in] policyRef The policy reference value.
147 * @param[in] hash_size The digest size of the used hash algorithm.
148 * @param[in] current_hash_alg The used has algorithm.
149 * @param[in,out] digest The policy digest which will be extended.
150 *
151 * @retval TSS2_RC_SUCCESS on success.
152 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
153 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
154 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
155 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
156 * the function.
157 */
158 static TSS2_RC
159 calculate_policy_key_param(
160 TPM2_CC command_code,
161 TPM2B_NAME *name,
162 TPM2B_NONCE *policyRef,
163 size_t hash_size,
164 TPMI_ALG_HASH current_hash_alg,
165 TPMU_HA *digest)
166 {
167 TSS2_RC r = TSS2_RC_SUCCESS;
168 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
169
170 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
171 return_if_error(r, "crypto hash start");
172
173 LOGBLOB_DEBUG((uint8_t *) digest, hash_size, "Digest Start");
174
175 /* First compute hash from passed policy digest and command code
176 and optionally the object name */
177 HASH_UPDATE_BUFFER(cryptoContext, digest, hash_size, r, cleanup);
178 HASH_UPDATE(cryptoContext, TPM2_CC, command_code, r, cleanup);
179 if (name && name->size > 0) {
180 LOGBLOB_DEBUG(&name->name[0], name->size, "Key name");
181 HASH_UPDATE_BUFFER(cryptoContext, &name->name[0],
182 name->size, r, cleanup);
183 }
184 r = ifapi_crypto_hash_finish(&cryptoContext,
185 (uint8_t *) digest, &hash_size);
186 LOGBLOB_DEBUG((uint8_t *) digest, hash_size, "Digest Finish");
187 return_if_error(r, "crypto hash finish");
188
189 /* Use policyRef for second hash computation */
190 if (policyRef) {
191 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
192 return_if_error(r, "crypto hash start");
193
194 HASH_UPDATE_BUFFER(cryptoContext, digest, hash_size, r, cleanup);
195 HASH_UPDATE_BUFFER(cryptoContext, &policyRef->buffer[0],
196 policyRef->size, r, cleanup);
197 r = ifapi_crypto_hash_finish(&cryptoContext,
198 (uint8_t *) digest, &hash_size);
199 return_if_error(r, "crypto hash finish");
200 }
201
202 cleanup:
203 if (cryptoContext)
204 ifapi_crypto_hash_abort(&cryptoContext);
205 return r;
206 }
207
208 /** Calculate a policy digest for a signed policy.
209 *
210 * Based on the command code, the public key, and the policy reference
211 * stored in the policy the new policy digest is computed by the function
212 * calculate_policy_key_param().
213 *
214 * @param[in] policy The policy with the public key and the policy reference.
215 * @param[in,out] current_digest The digest list which has to be updated.
216 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
217 *
218 * @retval TSS2_RC_SUCCESS on success.
219 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
220 * the function.
221 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
222 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
223 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
224 */
225 TSS2_RC
226 ifapi_calculate_policy_signed(
227 TPMS_POLICYSIGNED *policy,
228 TPML_DIGEST_VALUES *current_digest,
229 TPMI_ALG_HASH current_hash_alg)
230 {
231 TSS2_RC r = TSS2_RC_SUCCESS;
232 size_t digest_idx;
233 size_t hash_size;
234
235 LOG_DEBUG("call");
236
237 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
238 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
239 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
240 current_hash_alg);
241 }
242
243 /* Compute of the index of the current policy in the passed digest list */
244 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
245 return_if_error(r, "Get hash alg for digest.");
246
247 r = calculate_policy_key_param(TPM2_CC_PolicySigned,
248 &policy->publicKey,
249 &policy->policyRef, hash_size,
250 current_hash_alg,
251 &current_digest->digests[digest_idx].digest);
252 goto_if_error(r, "crypto hash start", cleanup);
253
254 cleanup:
255 return r;
256 }
257
258 /** Calculate a policy digest for a policy stored in an approved NV index.
259 *
260 * Based on the command code, and the computed NV name the new policy digest
261 * is computed by the function calculate_policy_key_param().
262 *
263 * @param[in] policy The policy with the public information of the NV index.
264 * @param[in,out] current_digest The digest list which has to be updated.
265 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
266 *
267 * @retval TSS2_RC_SUCCESS on success.
268 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
269 * the function.
270 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
271 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
272 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
273 */
274 TSS2_RC
275 ifapi_calculate_policy_authorize_nv(
276 TPMS_POLICYAUTHORIZENV *policy,
277 TPML_DIGEST_VALUES *current_digest,
278 TPMI_ALG_HASH current_hash_alg)
279 {
280 TSS2_RC r = TSS2_RC_SUCCESS;
281 size_t digest_idx;
282 size_t hash_size;
283 TPM2B_NAME nv_name;
284
285 LOG_DEBUG("call");
286
287 /* Written flag has to be set for policy calculation, because during
288 policy execution it will be set. */
289 policy->nvPublic.nvPublic.attributes |= TPMA_NV_WRITTEN;
290
291 r = ifapi_nv_get_name(&policy->nvPublic, &nv_name);
292 return_if_error(r, "Compute NV name");
293
294 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
295 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
296 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
297 current_hash_alg);
298 }
299
300 /* Compute of the index of the current policy in the passed digest list */
301 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
302 return_if_error(r, "Get hash alg for digest.");
303
304 r = calculate_policy_key_param(TPM2_CC_PolicyAuthorizeNV,
305 &nv_name,
306 NULL, hash_size, current_hash_alg,
307 &current_digest->digests[digest_idx].digest);
308 goto_if_error(r, "crypto hash start", cleanup);
309
310 cleanup:
311 return r;
312 }
313
314 /** Calculate a policy digest to allow duplication force a selected new parent.
315 *
316 * Based on the command code, the name of the new parent, and the include object
317 * switch the new policy digest is computed.
318 *
319 * @param[in] policy The policy with the new parent information.
320 * @param[in,out] current_digest The digest list which has to be updated.
321 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
322 *
323 * @retval TSS2_RC_SUCCESS on success.
324 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
325 * the function.
326 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
327 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
328 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
329 */
330 TSS2_RC
331 ifapi_calculate_policy_duplicate(
332 TPMS_POLICYDUPLICATIONSELECT *policy,
333 TPML_DIGEST_VALUES *current_digest,
334 TPMI_ALG_HASH current_hash_alg)
335 {
336 TSS2_RC r = TSS2_RC_SUCCESS;
337 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
338 size_t digest_idx;
339 size_t hash_size;
340
341 LOG_DEBUG("call");
342
343 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
344 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
345 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
346 current_hash_alg);
347 }
348
349 /* Compute of the index of the current policy in the passed digest list */
350 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
351 return_if_error(r, "Get hash alg for digest.");
352
353 LOG_TRACE("Compute policy");
354 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
355 return_if_error(r, "crypto hash start");
356
357 /* Update the policy digest */
358 HASH_UPDATE_BUFFER(cryptoContext,
359 &current_digest->digests[digest_idx].digest, hash_size,
360 r, cleanup);
361 HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyDuplicationSelect, r,
362 cleanup);
363 LOGBLOB_DEBUG(&policy->newParentName.name[0], policy->newParentName.size,
364 "Policy Duplicate Parent Name");
365 HASH_UPDATE_BUFFER(cryptoContext, &policy->newParentName.name[0],
366 policy->newParentName.size, r, cleanup);
367 HASH_UPDATE(cryptoContext, BYTE, policy->includeObject, r, cleanup);
368
369 r = ifapi_crypto_hash_finish(&cryptoContext,
370 (uint8_t *) & current_digest->
371 digests[digest_idx].digest, &hash_size);
372 return_if_error(r, "crypto hash finish");
373
374 LOGBLOB_DEBUG((uint8_t *) & current_digest->digests[digest_idx].digest,
375 hash_size, "Policy Duplicate digest");
376
377 cleanup:
378 if (cryptoContext)
379 ifapi_crypto_hash_abort(&cryptoContext);
380 return r;
381 }
382
383 /** Calculate a policy digest for a placeholder policy.
384 *
385 * The placeholder policy can be extended during execution by a
386 * signed policy, which can be verified by using the parameters of
387 * this placeholder policy.
388 * Based on the command code, the key name of the signing key and
389 * a policy reference the new policy digest is computed by the
390 * function calculate_policy_key_param().
391 *
392 * @param[in] policy The policy with the name of the public key and the
393 * policy reference.
394 * @param[in,out] current_digest The digest list which has to be updated.
395 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
396 *
397 * @retval TSS2_RC_SUCCESS on success.
398 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
399 * the function.
400 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
401 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
402 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
403 */
404 TSS2_RC
405 ifapi_calculate_policy_authorize(
406 TPMS_POLICYAUTHORIZE *policy,
407 TPML_DIGEST_VALUES *current_digest,
408 TPMI_ALG_HASH current_hash_alg)
409 {
410 TSS2_RC r = TSS2_RC_SUCCESS;
411 size_t digest_idx;
412 size_t hash_size;
413
414 LOG_DEBUG("call");
415
416 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
417 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
418 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
419 current_hash_alg);
420 }
421
422 /* Compute of the index of the current policy in the passed digest list */
423 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
424 return_if_error(r, "Get hash alg for digest.");
425
426 r = calculate_policy_key_param(TPM2_CC_PolicyAuthorize,
427 &policy->keyName,
428 &policy->policyRef, hash_size,
429 current_hash_alg,
430 &current_digest->digests[digest_idx].digest);
431 goto_if_error(r, "crypto hash start", cleanup);
432
433 cleanup:
434 return r;
435 }
436
437 /** Calculate a policy for adding secret-based authorization.
438 *
439 * During execution proving the knowledge of the secrect auth value of a certain
440 * object is required. The name of this object and a policy reference is used
441 * for policy calculation.
442 * Based on the command code, the object name and a policy reference the new
443 * policy digest is computed by the function calculate_policy_key_param().
444 *
445 * @param[in] policy The policy with the object name of the object to be
446 * authorized and the policy reference.
447 * @param[in,out] current_digest The digest list which has to be updated.
448 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
449 *
450 * @retval TSS2_RC_SUCCESS on success.
451 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
452 * the function.
453 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
454 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
455 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
456 */
457 TSS2_RC
458 ifapi_calculate_policy_secret(
459 TPMS_POLICYSECRET *policy,
460 TPML_DIGEST_VALUES *current_digest,
461 TPMI_ALG_HASH current_hash_alg)
462 {
463 TSS2_RC r = TSS2_RC_SUCCESS;
464 size_t digest_idx;
465 size_t hash_size;
466
467 LOG_DEBUG("call");
468
469 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
470 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
471 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
472 current_hash_alg);
473 }
474
475 /* Compute of the index of the current policy in the passed digest list */
476 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
477 return_if_error(r, "Get hash alg for digest.");
478
479 /* Update the policy */
480 r = calculate_policy_key_param(TPM2_CC_PolicySecret,
481 (TPM2B_NAME *)&policy->objectName,
482 &policy->policyRef, hash_size,
483 current_hash_alg,
484 &current_digest->digests[digest_idx].digest);
485 goto_if_error(r, "crypto hash start", cleanup);
486
487 cleanup:
488 return r;
489 }
490
491 /** Calculate a policy for for comparing current TPM timers with the policy.
492 *
493 * The timer value and the operation for comparison defined in the policy will
494 * bu used to update the policy digest.
495 * The offset which is supported by the TPM policy for FAPI will be 0.
496 *
497 * @param[in] policy The policy with the timer value and the operation for
498 * comparison.
499 * @param[in,out] current_digest The digest list which has to be updated.
500 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
501 *
502 * @retval TSS2_RC_SUCCESS on success.
503 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
504 * the function.
505 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
506 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
507 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
508 */
509 TSS2_RC
510 ifapi_calculate_policy_counter_timer(
511 TPMS_POLICYCOUNTERTIMER *policy,
512 TPML_DIGEST_VALUES *current_digest,
513 TPMI_ALG_HASH current_hash_alg)
514 {
515 TSS2_RC r = TSS2_RC_SUCCESS;
516 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
517 size_t digest_idx;
518 size_t hash_size;
519 TPM2B_DIGEST counter_timer_hash;
520
521 LOG_DEBUG("call");
522
523 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
524 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
525 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
526 current_hash_alg);
527 }
528
529 /* Compute of the index of the current policy in the passed digest list */
530 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
531 return_if_error(r, "Get hash alg for digest.");
532
533 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
534 return_if_error(r, "crypto hash start");
535
536 /* Compute a has value from the offset, the timer value and the operation. */
537 HASH_UPDATE_BUFFER(cryptoContext, &policy->operandB.buffer[0],
538 policy->operandB.size, r, cleanup);
539 HASH_UPDATE(cryptoContext, UINT16, policy->offset, r, cleanup);
540 HASH_UPDATE(cryptoContext, UINT16, policy->operation, r, cleanup);
541
542 r = ifapi_crypto_hash_finish(&cryptoContext,
543 (uint8_t *) &counter_timer_hash.buffer[0], &hash_size);
544 return_if_error(r, "crypto hash finish");
545
546 /* Extend the policy digest from the hash value computed above and the
547 command code. */
548 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
549 return_if_error(r, "crypto hash start");
550
551 HASH_UPDATE_BUFFER(cryptoContext,
552 &current_digest->digests[digest_idx].digest, hash_size,
553 r, cleanup);
554 HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyCounterTimer, r, cleanup);
555 HASH_UPDATE_BUFFER(cryptoContext, &counter_timer_hash.buffer[0],
556 hash_size, r, cleanup);
557 r = ifapi_crypto_hash_finish(&cryptoContext,
558 (uint8_t *) &current_digest->digests[digest_idx].digest,
559 &hash_size);
560 cleanup:
561 if (cryptoContext)
562 ifapi_crypto_hash_abort(&cryptoContext);
563 return r;
564 }
565
566 /** Update policy if only the command codes are used.
567 *
568 * Some simple policies use onle one or two command codes for policy calculation.
569 *
570 * @param[in] command_code1 The first command code for policy extension.
571 * Can be NULL.
572 * @param[in] command_code2 The second command code for policy extension.
573 * Can be NULL.
574 * @param[in,out] current_digest The digest list which has to be updated.
575 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
576 *
577 * @retval TSS2_RC_SUCCESS on success.
578 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
579 * the function.
580 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
581 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
582 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
583 */
584 TSS2_RC
585 ifapi_calculate_simple_policy(
586 TPM2_CC command_code1,
587 TPM2_CC command_code2,
588 TPML_DIGEST_VALUES *current_digest,
589 TPMI_ALG_HASH current_hash_alg)
590 {
591 TSS2_RC r = TSS2_RC_SUCCESS;
592 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
593 size_t digest_idx;
594 size_t hash_size;
595
596 LOG_DEBUG("call");
597
598 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
599 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
600 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
601 current_hash_alg);
602 }
603
604 /* Compute of the index of the current policy in the passed digest list */
605 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
606 return_if_error(r, "Get hash alg for digest.");
607
608 /* Update the policy */
609 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
610 return_if_error(r, "crypto hash start");
611
612 HASH_UPDATE_BUFFER(cryptoContext,
613 &current_digest->digests[digest_idx].digest, hash_size,
614 r, cleanup);
615 if (command_code1) {
616 HASH_UPDATE(cryptoContext, TPM2_CC, command_code1, r, cleanup);
617 }
618 if (command_code2) {
619 HASH_UPDATE(cryptoContext, TPM2_CC, command_code2, r, cleanup);
620 }
621 r = ifapi_crypto_hash_finish(&cryptoContext,
622 (uint8_t *) &current_digest->digests[digest_idx].digest,
623 &hash_size);
624
625 cleanup:
626 if (cryptoContext)
627 ifapi_crypto_hash_abort(&cryptoContext);
628 return r;
629 }
630
631 /** Update policy with command code policy physical presence.
632 *
633 * The policy will be updated with the function ifapi_calculate_simple_policy()
634 *
635 * @param[in] policy The policy physical presence.
636 * @param[in,out] current_digest The digest list which has to be updated.
637 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
638 *
639 * @retval TSS2_RC_SUCCESS on success.
640 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
641 * the function.
642 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
643 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
644 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
645 */
646 TSS2_RC
647 ifapi_calculate_policy_physical_presence(
648 TPMS_POLICYPHYSICALPRESENCE *policy,
649 TPML_DIGEST_VALUES *current_digest,
650 TPMI_ALG_HASH current_hash_alg)
651 {
652 TSS2_RC r = TSS2_RC_SUCCESS;
653 (void)policy;
654
655 LOG_DEBUG("call");
656
657 r = ifapi_calculate_simple_policy(TPM2_CC_PolicyPhysicalPresence, 0,
658 current_digest, current_hash_alg);
659 return_if_error(r, "Calculate policy for command code.");
660
661 return r;
662 }
663
664 /** Update policy with command code of policy auth value.
665 *
666 * The policy will be updated with the function ifapi_calculate_simple_policy()
667 *
668 * @param[in] policy The policy auth value.
669 * @param[in,out] current_digest The digest list which has to be updated.
670 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
671 *
672 * @retval TSS2_RC_SUCCESS on success.
673 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
674 * the function.
675 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
676 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
677 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
678 */
679 TSS2_RC
680 ifapi_calculate_policy_auth_value(
681 TPMS_POLICYAUTHVALUE *policy,
682 TPML_DIGEST_VALUES *current_digest,
683 TPMI_ALG_HASH current_hash_alg)
684 {
685 TSS2_RC r = TSS2_RC_SUCCESS;
686 (void)policy;
687
688 LOG_DEBUG("call");
689
690 r = ifapi_calculate_simple_policy(TPM2_CC_PolicyAuthValue, 0,
691 current_digest, current_hash_alg);
692 return_if_error(r, "Calculate policy auth value.");
693
694 return r;
695 }
696
697 /** Update policy with the command code of policy password.
698 *
699 * The policy will be updated with the function ifapi_calculate_simple_policy()
700 *
701 * @param[in] policy The policy password.
702 * @param[in,out] current_digest The digest list which has to be updated.
703 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
704 *
705 * @retval TSS2_RC_SUCCESS on success.
706 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
707 * the function.
708 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
709 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
710 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
711 */
712 TSS2_RC
713 ifapi_calculate_policy_password(
714 TPMS_POLICYPASSWORD *policy,
715 TPML_DIGEST_VALUES *current_digest,
716 TPMI_ALG_HASH current_hash_alg)
717 {
718 TSS2_RC r = TSS2_RC_SUCCESS;
719 (void)policy;
720
721 LOG_DEBUG("call");
722
723 r = ifapi_calculate_simple_policy(TPM2_CC_PolicyAuthValue, 0,
724 current_digest, current_hash_alg);
725 return_if_error(r, "Calculate policy password.");
726
727 return r;
728 }
729
730 /** Update policy command code with a command code defined in the policy.
731 *
732 * For the update two command codes will be used. The command code of
733 * policy command code and the passed command code.
734 * The policy will be updated with the function ifapi_calculate_simple_policy()
735 *
736 * @param[in] policy The policy command code with the second command code.
737 * @param[in,out] current_digest The digest list which has to be updated.
738 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
739 *
740 * @retval TSS2_RC_SUCCESS on success.
741 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
742 * the function.
743 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
744 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
745 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
746 */
747 TSS2_RC
748 ifapi_calculate_policy_command_code(
749 TPMS_POLICYCOMMANDCODE *policy,
750 TPML_DIGEST_VALUES *current_digest,
751 TPMI_ALG_HASH current_hash_alg)
752 {
753 TSS2_RC r = TSS2_RC_SUCCESS;
754
755 LOG_DEBUG("call");
756
757 r = ifapi_calculate_simple_policy(TPM2_CC_PolicyCommandCode, policy->code,
758 current_digest, current_hash_alg);
759 return_if_error(r, "Calculate policy for command code.");
760
761 return r;
762 }
763
764 /** Compute policy if only a digest and a command code are needed for extension.
765 *
766 * @param[in] digest the digest which will be used for policy extension.
767 * @param[in,out] current_digest The digest list which has to be updated.
768 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
769 * @param[in] command_code The compute of the command which did compute the digest.
770 *
771 * @retval TSS2_RC_SUCCESS on success.
772 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
773 * the function.
774 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
775 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
776 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
777 */
778 TSS2_RC
779 ifapi_calculate_policy_digest_hash(
780 TPM2B_DIGEST *digest,
781 TPML_DIGEST_VALUES *current_digest,
782 TPMI_ALG_HASH current_hash_alg,
783 TPM2_CC command_code)
784 {
785 TSS2_RC r = TSS2_RC_SUCCESS;
786 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
787 size_t digest_idx;
788 size_t hash_size;
789
790 LOG_DEBUG("call");
791
792 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
793 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
794 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
795 current_hash_alg);
796 }
797
798 /* Compute of the index of the current policy in the passed digest list */
799 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
800 return_if_error(r, "Get hash alg for digest.");
801
802 /* Update the policy. */
803 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
804 return_if_error(r, "crypto hash start");
805
806 HASH_UPDATE_BUFFER(cryptoContext,
807 &current_digest->digests[digest_idx].digest, hash_size,
808 r, cleanup);
809 HASH_UPDATE(cryptoContext, TPM2_CC, command_code, r, cleanup);
810 HASH_UPDATE_BUFFER(cryptoContext, &digest->buffer[0],
811 digest->size, r, cleanup);
812 r = ifapi_crypto_hash_finish(&cryptoContext,
813 (uint8_t *) &current_digest->digests[digest_idx].digest,
814 &hash_size);
815 cleanup:
816 if (cryptoContext)
817 ifapi_crypto_hash_abort(&cryptoContext);
818 return r;
819 }
820
821 /** Compute policy bound to a specific set of TPM entities.
822 *
823 * The policy digest will be updated with the function
824 * ifapi_calculate_policy_digest_hash() which will add the hash of the
825 * entity name list.
826 *
827 * @param[in] policy The policy with the list of entity names.
828 * @param[in,out] current_digest The digest list which has to be updated.
829 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
830 *
831 * @retval TSS2_RC_SUCCESS on success.
832 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
833 * the function.
834 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
835 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
836 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
837 */
838 TSS2_RC
839 ifapi_calculate_policy_name_hash(
840 TPMS_POLICYNAMEHASH *policy,
841 TPML_DIGEST_VALUES *current_digest,
842 TPMI_ALG_HASH current_hash_alg)
843 {
844 TSS2_RC r = TSS2_RC_SUCCESS;
845 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
846 size_t hash_size;
847 size_t i;
848
849 LOG_DEBUG("call");
850
851 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
852 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
853 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
854 current_hash_alg);
855 }
856
857 /* Compute of the index of the current policy in the passed digest list */
858 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
859 return_if_error(r, "crypto hash start");
860
861 /* Compute name hash from the list of object names */
862 for (i = 0; i <= policy->count; i++) {
863 HASH_UPDATE_BUFFER(cryptoContext, &policy->objectNames[i].name[0],
864 policy->objectNames[i].size, r,
865 cleanup);
866 }
867 r = ifapi_crypto_hash_finish(&cryptoContext,
868 (uint8_t *) &policy->nameHash.buffer[0],
869 &hash_size);
870 return_if_error(r, "crypto hash finish");
871
872 policy->nameHash.size = hash_size;
873
874 /* Update the policy with the computed hash value of the name list and
875 the command code. */
876 r = ifapi_calculate_policy_digest_hash(&policy->nameHash,
877 current_digest,
878 current_hash_alg, TPM2_CC_PolicyNameHash);
879 return_if_error(r, "Calculate digest hash for policy");
880
881 cleanup:
882 if (cryptoContext)
883 ifapi_crypto_hash_abort(&cryptoContext);
884 return r;
885 }
886
887 /** Compute policy bound to a specific command and command parameters.
888 *
889 * The cp hash value and the command code will be updated by the
890 * function ifapi_calculate_policy_digest_hash().
891 *
892 * @param[in] policy The policy with the cp hash value.
893 * @param[in,out] current_digest The digest list which has to be updated.
894 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
895 *
896 * @retval TSS2_RC_SUCCESS on success.
897 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
898 * the function.
899 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
900 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
901 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
902 */
903 TSS2_RC
904 ifapi_calculate_policy_cp_hash(
905 TPMS_POLICYCPHASH *policy,
906 TPML_DIGEST_VALUES *current_digest,
907 TPMI_ALG_HASH current_hash_alg)
908 {
909 TSS2_RC r = TSS2_RC_SUCCESS;
910
911 LOG_DEBUG("call");
912
913 r = ifapi_calculate_policy_digest_hash(&policy->cpHash,
914 current_digest, current_hash_alg,
915 TPM2_CC_PolicyCpHash);
916 return_if_error(r, "Calculate digest hash for policy");
917
918 return r;
919 }
920
921 /** Compute policy which limits authorization to a specific locality.
922 *
923 * @param[in] policy The policy with the locality.
924 * @param[in,out] current_digest The digest list which has to be updated.
925 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
926 *
927 * @retval TSS2_RC_SUCCESS on success.
928 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
929 * the function.
930 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
931 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
932 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
933 */
934 TSS2_RC
935 ifapi_calculate_policy_locality(
936 TPMS_POLICYLOCALITY *policy,
937 TPML_DIGEST_VALUES *current_digest,
938 TPMI_ALG_HASH current_hash_alg)
939 {
940 TSS2_RC r = TSS2_RC_SUCCESS;
941 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
942 size_t digest_idx;
943 size_t hash_size;
944
945 LOG_DEBUG("call");
946
947 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
948 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
949 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
950 current_hash_alg);
951 }
952
953 /* Compute of the index of the current policy in the passed digest list */
954 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
955 return_if_error(r, "Get hash alg for digest.");
956
957 /* Update the policy */
958 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
959 return_if_error(r, "crypto hash start");
960
961 HASH_UPDATE_BUFFER(cryptoContext,
962 &current_digest->digests[digest_idx].digest, hash_size,
963 r, cleanup);
964 HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyLocality, r, cleanup);
965 HASH_UPDATE(cryptoContext, BYTE, policy->locality, r, cleanup);
966 r = ifapi_crypto_hash_finish(&cryptoContext,
967 (uint8_t *) & current_digest->
968 digests[digest_idx].digest, &hash_size);
969
970 cleanup:
971 if (cryptoContext)
972 ifapi_crypto_hash_abort(&cryptoContext);
973 return r;
974 }
975
976 /** Compute policy bound to bound to the TPMA_NV_WRITTEN attributes.
977 *
978 * The expected value of the NV written attribute is part of the policy.
979 *
980 * @param[in] policy The policy with the expected attribute value.
981 * @param[in,out] current_digest The digest list which has to be updated.
982 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
983 *
984 * @retval TSS2_RC_SUCCESS on success.
985 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
986 * the function.
987 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
988 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
989 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
990 */
991 TSS2_RC
992 ifapi_calculate_policy_nv_written(
993 TPMS_POLICYNVWRITTEN *policy,
994 TPML_DIGEST_VALUES *current_digest,
995 TPMI_ALG_HASH current_hash_alg)
996 {
997 TSS2_RC r = TSS2_RC_SUCCESS;
998 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
999 size_t digest_idx;
1000 size_t hash_size;
1001
1002 LOG_DEBUG("call");
1003
1004 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
1005 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
1006 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
1007 current_hash_alg);
1008 }
1009
1010 /* Compute of the index of the current policy in the passed digest list */
1011 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
1012 return_if_error(r, "Get hash alg for digest.");
1013
1014 /* Update the policy */
1015 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
1016 return_if_error(r, "crypto hash start");
1017
1018 HASH_UPDATE_BUFFER(cryptoContext,
1019 &current_digest->digests[digest_idx].digest, hash_size,
1020 r, cleanup);
1021 HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyNvWritten, r, cleanup);
1022 /* Update the expected attribute value. */
1023 HASH_UPDATE(cryptoContext, BYTE, policy->writtenSet, r, cleanup);
1024 r = ifapi_crypto_hash_finish(&cryptoContext,
1025 (uint8_t *) & current_digest->
1026 digests[digest_idx].digest, &hash_size);
1027
1028 cleanup:
1029 if (cryptoContext)
1030 ifapi_crypto_hash_abort(&cryptoContext);
1031 return r;
1032 }
1033
1034 /** Compute policy bound to the content of an NV index.
1035 *
1036 * The value used for comparison, the compare operation and an
1037 * offset for the NV index are part of the policy.
1038 *
1039 * @param[in] policy The policy with the expected values used for comparison.
1040 * @param[in,out] current_digest The digest list which has to be updated.
1041 * @param[in] current_hash_alg The hash algorithm used for the policy computation.
1042 *
1043 * @retval TSS2_RC_SUCCESS on success.
1044 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1045 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1046 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1047 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1048 * the function.
1049 */
1050 TSS2_RC
1051 ifapi_calculate_policy_nv(
1052 TPMS_POLICYNV *policy,
1053 TPML_DIGEST_VALUES *current_digest,
1054 TPMI_ALG_HASH current_hash_alg)
1055 {
1056 TSS2_RC r = TSS2_RC_SUCCESS;
1057 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
1058 TPM2B_NAME nv_name;
1059 size_t hash_size;
1060 TPM2B_DIGEST nv_hash;
1061 size_t digest_idx;
1062
1063 LOG_DEBUG("call");
1064
1065 memset(&nv_name, 0, sizeof(TPM2B_NAME));
1066
1067 /* Compute NV name from public info */
1068
1069 r = ifapi_nv_get_name(&policy->nvPublic, &nv_name);
1070 return_if_error(r, "Compute NV name");
1071
1072 /* Compute of the index of the current policy in the passed digest list */
1073 r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
1074 return_if_error(r, "Get hash alg for digest.");
1075
1076 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
1077 return_if_error(r, "crypto hash start");
1078
1079 /* Compute the hash for the compare operation. */
1080 HASH_UPDATE_BUFFER(cryptoContext, &policy->operandB.buffer[0],
1081 policy->operandB.size, r, cleanup);
1082 HASH_UPDATE(cryptoContext, UINT16, policy->offset, r, cleanup);
1083 HASH_UPDATE(cryptoContext, UINT16, policy->operation, r, cleanup);
1084 r = ifapi_crypto_hash_finish(&cryptoContext,
1085 (uint8_t *) &nv_hash.buffer[0], &hash_size);
1086 return_if_error(r, "crypto hash finish");
1087
1088 nv_hash.size = hash_size;
1089
1090 /* Update the policy with the hash of the compare operation and the NV name. */
1091 r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
1092 return_if_error(r, "crypto hash start");
1093
1094 HASH_UPDATE_BUFFER(cryptoContext,
1095 &current_digest->digests[digest_idx].digest, hash_size,
1096 r, cleanup);
1097 HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyNV, r, cleanup);
1098 HASH_UPDATE_BUFFER(cryptoContext, &nv_hash.buffer[0], nv_hash.size, r, cleanup)
1099 HASH_UPDATE_BUFFER(cryptoContext, &nv_name.name[0], nv_name.size, r, cleanup);
1100 r = ifapi_crypto_hash_finish(&cryptoContext,
1101 (uint8_t *) &current_digest->digests[digest_idx].digest,
1102 &hash_size);
1103 return_if_error(r, "crypto hash finish");
1104
1105 cleanup:
1106 if (cryptoContext)
1107 ifapi_crypto_hash_abort(&cryptoContext);
1108 return r;
1109 }
1110
1111 /** Compute a list of policies to enable authorization options.
1112 *
1113 * First the policy digest will be computed for every branch.
1114 * After that the policy digest will be reset to zero and extended by the
1115 * list of computed policy digests of the branches.
1116 *
1117 * @param[in] policyOr The policy with the possible policy branches.
1118 * @param[in,out] current_digest The digest list which has to be updated.
1119 * @param[in] hash_alg The hash algorithm used for the policy computation.
1120 * @param[in] hash_size The size of the policy digest.
1121 * @param[in] digest_idx The index of the current policy in the passed digest list.
1122 *
1123 * @retval TSS2_RC_SUCCESS on success.
1124 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1125 * the function.
1126 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1127 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1128 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1129 */
1130 TSS2_RC
1131 ifapi_calculate_policy_or(
1132 TPMS_POLICYOR *policyOr,
1133 TPML_DIGEST_VALUES *current_digest,
1134 TPMI_ALG_HASH hash_alg,
1135 size_t hash_size,
1136 size_t digest_idx)
1137 {
1138 size_t i;
1139 TSS2_RC r = TSS2_RC_SUCCESS;
1140 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
1141
1142 for (i = 0; i < policyOr->branches->count; i++) {
1143 /* Compute the policy digest for every branch. */
1144 copy_policy_digest(&policyOr->branches->authorizations[i].policyDigests,
1145 current_digest, digest_idx, hash_size,
1146 "Copy or digest");
1147
1148 r = ifapi_calculate_policy(policyOr->branches->authorizations[i].policy,
1149 &policyOr->branches->authorizations[i].
1150 policyDigests, hash_alg, hash_size,
1151 digest_idx);
1152 log_policy_digest(&policyOr->branches->authorizations[i].policyDigests,
1153 digest_idx, hash_size, "Branch digest");
1154
1155 return_if_error(r, "Compute policy.");
1156 }
1157 /* Reset the or policy digest because the digest is included in all sub policies */
1158 memset(&current_digest->digests[digest_idx], 0, hash_size);
1159 r = ifapi_crypto_hash_start(&cryptoContext, hash_alg);
1160 return_if_error(r, "crypto hash start");
1161 r = ifapi_crypto_hash_update(cryptoContext, (const uint8_t *)
1162 &current_digest->digests[digest_idx].digest,
1163 hash_size);
1164 goto_if_error(r, "crypto hash update", cleanup);
1165
1166 /* Start with the update of the reset digest. */
1167 uint8_t buffer[sizeof(TPM2_CC)];
1168 size_t offset = 0;
1169 r = Tss2_MU_TPM2_CC_Marshal(TPM2_CC_PolicyOR,
1170 &buffer[0], sizeof(TPM2_CC), &offset);
1171 goto_if_error(r, "Marshal cc", cleanup);
1172
1173 r = ifapi_crypto_hash_update(cryptoContext,
1174 (const uint8_t *)&buffer[0], sizeof(TPM2_CC));
1175 goto_if_error(r, "crypto hash update", cleanup);
1176
1177 /* Update the digest with the complete list of computed digests of the branches. */
1178 for (i = 0; i < policyOr->branches->count; i++) {
1179 r = ifapi_crypto_hash_update(cryptoContext, (const uint8_t *)
1180 &policyOr->branches->authorizations[i]
1181 .policyDigests.digests[digest_idx].digest,
1182 hash_size);
1183 log_policy_digest(&policyOr->branches->authorizations[i].policyDigests,
1184 digest_idx, hash_size, "Or branch");
1185 current_digest->count =
1186 policyOr->branches->authorizations[i].policyDigests.count;
1187 goto_if_error(r, "crypto hash update", cleanup);
1188 }
1189 current_digest->digests[digest_idx].hashAlg = hash_alg;
1190 r = ifapi_crypto_hash_finish(&cryptoContext,
1191 (uint8_t *) & current_digest->
1192 digests[digest_idx].digest, &hash_size);
1193 log_policy_digest(current_digest, digest_idx, hash_size, "Final or digest");
1194 goto_if_error(r, "crypto hash finish", cleanup);
1195
1196 cleanup:
1197 if (cryptoContext)
1198 ifapi_crypto_hash_abort(&cryptoContext);
1199 return r;
1200 }
1201
1202 /** Compute policy digest for a list of policies.
1203 *
1204 * Every policy in the list will update the previous policy. Thus the final
1205 * policy digest will describe the sequential execution of the policy list.
1206 *
1207 * @param[in] policy The policy with the policy list.
1208 * @param[in,out] policyDigests The digest list which has to be updated.
1209 * @param[in] hash_alg The hash algorithm used for the policy computation.
1210 * @param[in] hash_size The size of the policy digest.
1211 * @param[in] digest_idx The index of the current policy in the passed digest list.
1212 *
1213 * @retval TSS2_RC_SUCCESS on success.
1214 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1215 * the function.
1216 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1217 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1218 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1219 */
1220 TSS2_RC
1221 ifapi_calculate_policy(
1222 TPML_POLICYELEMENTS *policy,
1223 TPML_DIGEST_VALUES *policyDigests,
1224 TPMI_ALG_HASH hash_alg,
1225 size_t hash_size,
1226 size_t digest_idx)
1227 {
1228 size_t i;
1229 TSS2_RC r = TSS2_RC_SUCCESS;
1230
1231 for (i = 0; i < policy->count; i++) {
1232
1233 copy_policy_digest(&policy->elements[i].policyDigests,
1234 policyDigests, digest_idx, hash_size,
1235 "Copy policy digest (to)");
1236
1237 switch (policy->elements[i].type) {
1238
1239 case POLICYPCR:
1240 r = ifapi_compute_policy_pcr(&policy->elements[i].element.PolicyPCR,
1241 &policy->elements[i].policyDigests,
1242 hash_alg);
1243 return_if_error(r, "Compute policy pcr");
1244 break;
1245
1246 case POLICYSIGNED:
1247 r = ifapi_calculate_policy_signed(&policy->elements[i].element.
1248 PolicySigned,
1249 &policy->elements[i].
1250 policyDigests, hash_alg);
1251 return_if_error(r, "Compute policy nv");
1252
1253 break;
1254
1255 case POLICYDUPLICATIONSELECT:
1256 r = ifapi_calculate_policy_duplicate(&policy->elements[i].element.
1257 PolicyDuplicationSelect,
1258 &policy->elements[i].
1259 policyDigests, hash_alg);
1260 return_if_error(r, "Compute policy duplication select");
1261
1262 break;
1263
1264 case POLICYAUTHORIZENV:
1265 r = ifapi_calculate_policy_authorize_nv(&policy->elements[i].
1266 element.PolicyAuthorizeNv,
1267 &policy->elements[i].
1268 policyDigests, hash_alg);
1269 return_if_error(r, "Compute policy authorizeg");
1270
1271 break;
1272
1273 case POLICYAUTHORIZE:
1274 r = ifapi_calculate_policy_authorize(&policy->elements[i].element.
1275 PolicyAuthorize,
1276 &policy->elements[i].
1277 policyDigests, hash_alg);
1278 return_if_error(r, "Compute policy authorizeg");
1279
1280 break;
1281
1282 case POLICYSECRET:
1283 r = ifapi_calculate_policy_secret(&policy->elements[i].element.
1284 PolicySecret,
1285 &policy->elements[i].
1286 policyDigests, hash_alg);
1287 return_if_error(r, "Compute policy nv");
1288
1289 break;
1290
1291 case POLICYOR:
1292 r = ifapi_calculate_policy_or(&policy->elements[i].element.PolicyOr,
1293 &policy->elements[i].policyDigests,
1294 hash_alg, hash_size, digest_idx);
1295 return_if_error(r, "Compute policy or");
1296
1297 break;
1298
1299 case POLICYNV:
1300 r = ifapi_calculate_policy_nv(&policy->elements[i].element.PolicyNV,
1301 &policy->elements[i].policyDigests,
1302 hash_alg);
1303 return_if_error(r, "Compute policy nv");
1304
1305 break;
1306
1307 case POLICYNVWRITTEN:
1308 r = ifapi_calculate_policy_nv_written(&policy->elements[i].element.
1309 PolicyNvWritten,
1310 &policy->elements[i].
1311 policyDigests, hash_alg);
1312 return_if_error(r, "Compute policy nv written");
1313 break;
1314
1315 case POLICYCOUNTERTIMER:
1316 r = ifapi_calculate_policy_counter_timer(
1317 &policy->elements[i].element.PolicyCounterTimer,
1318 &policy->elements[i].policyDigests, hash_alg);
1319 return_if_error(r, "Compute policy counter timer");
1320 break;
1321
1322 case POLICYPHYSICALPRESENCE:
1323 r = ifapi_calculate_policy_physical_presence(
1324 &policy->elements[i].element.PolicyPhysicalPresence,
1325 &policy->elements[i].policyDigests, hash_alg);
1326 return_if_error(r, "Compute policy physical presence");
1327 break;
1328
1329 case POLICYAUTHVALUE:
1330 r = ifapi_calculate_policy_auth_value(&policy->elements[i].element.PolicyAuthValue,
1331 &policy->elements[i].policyDigests, hash_alg);
1332 return_if_error(r, "Compute policy auth value");
1333 break;
1334
1335 case POLICYPASSWORD:
1336 r = ifapi_calculate_policy_password(&policy->elements[i].element.PolicyPassword,
1337 &policy->elements[i].policyDigests, hash_alg);
1338 return_if_error(r, "Compute policy password");
1339 break;
1340
1341 case POLICYCOMMANDCODE:
1342 r = ifapi_calculate_policy_command_code(&policy->elements[i].element.PolicyCommandCode,
1343 &policy->elements[i].policyDigests, hash_alg);
1344 return_if_error(r, "Compute policy physical presence");
1345 break;
1346
1347 case POLICYNAMEHASH:
1348 r = ifapi_calculate_policy_name_hash(&policy->elements[i].element.PolicyNameHash,
1349 &policy->elements[i].policyDigests, hash_alg);
1350 return_if_error(r, "Compute policy name hash");
1351 break;
1352
1353 case POLICYCPHASH:
1354 r = ifapi_calculate_policy_cp_hash(&policy->elements[i].element.PolicyCpHash,
1355 &policy->elements[i].policyDigests, hash_alg);
1356 return_if_error(r, "Compute policy cp hash");
1357 break;
1358
1359 case POLICYLOCALITY:
1360 r = ifapi_calculate_policy_locality(&policy->elements[i].element.PolicyLocality,
1361 &policy->elements[i].policyDigests, hash_alg);
1362 return_if_error(r, "Compute policy locality");
1363 break;
1364
1365 case POLICYACTION:
1366 /* This does not alter the policyDigest */
1367 break;
1368
1369 default:
1370 return_error(TSS2_FAPI_RC_BAD_VALUE,
1371 "Policy not implemented");
1372 }
1373
1374 copy_policy_digest(policyDigests, &policy->elements[i].policyDigests,
1375 digest_idx, hash_size, "Copy policy digest (from)");
1376 }
1377 return r;
1378 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef FAPI_POLICY_CALCULATE_H
6 #define FAPI_POLICY_CALCULATE_H
7
8 #include <stdint.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <json-c/json.h>
13 #include <json-c/json_util.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17 #include "fapi_int.h"
18 //#include "fapi_policy.h"
19 //#include "ifapi_keystore.h"
20
21 TSS2_RC
22 ifapi_calculate_policy(
23 TPML_POLICYELEMENTS *policy,
24 TPML_DIGEST_VALUES *policyDigests,
25 TPMI_ALG_HASH hash_alg,
26 size_t hash_size,
27 size_t digest_idx);
28
29 #endif /* FAPI_POLICY_CALCULATE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "fapi_util.h"
14 #include "fapi_policy.h"
15 #include "ifapi_helpers.h"
16 #include "fapi_crypto.h"
17 #include "ifapi_policy_instantiate.h"
18 #include "ifapi_policyutil_execute.h"
19 #include "ifapi_policy_execute.h"
20 #include "ifapi_policy_callbacks.h"
21 #include "tss2_mu.h"
22
23 #define LOGMODULE fapi
24 #include "util/log.h"
25 #include "util/aux_util.h"
26
27 /** Determine the auth object of a NV index.
28 *
29 * The auth object is determined depending on the object flags.
30 *
31 * @param[in] nv_object The internal FAPI object representing the NV index.
32 * @param[out] nv_index The ESYS handle of the NV index.
33 * @param[out] auth_object The internal FAPI auth object.
34 * @param[out] auth_index The ESYS handle of the auth object.
35 * @retval TSS2_RC_SUCCESS on success.
36 */
37 static void
38 get_nv_auth_object(
39 IFAPI_OBJECT *nv_object,
40 ESYS_TR nv_index,
41 IFAPI_OBJECT *auth_object,
42 ESYS_TR *auth_index)
43 {
44 if (nv_object->misc.nv.public.nvPublic.attributes & TPMA_NV_PPREAD) {
45 ifapi_init_hierarchy_object(auth_object, ESYS_TR_RH_PLATFORM);
46 *auth_index = ESYS_TR_RH_PLATFORM;
47 } else {
48 if (nv_object->misc.nv.public.nvPublic.attributes & TPMA_NV_OWNERREAD) {
49 ifapi_init_hierarchy_object(auth_object, ESYS_TR_RH_OWNER);
50 *auth_index = ESYS_TR_RH_OWNER;
51 } else {
52 *auth_index = nv_index;
53 *auth_object = *nv_object;
54 }
55 }
56 }
57
58 /** Get public data of a key from keystore.
59 *
60 * @param[in] path The relative path of the key.
61 * @param[out] public The caller allocated public structure.
62 * @param[in,out] ctx The context to access io and keystore module and to store
63 * the io state.
64 * @retval TSS2_RC_SUCCESS on success.
65 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be loaded.
66 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
67 * internal operations or return parameters.
68 * @retval TSS2_FAPI_RC_BAD_TEMPLATE If the loaded template is not
69 * appropriate for this operation.
70 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
71 * the function.
72 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
73 * this function needs to be called again.
74 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
75 * operation already pending.
76 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
77 * during authorization.
78 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
79 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
80 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
81 */
82 TSS2_RC
83 ifapi_get_key_public(
84 const char *path,
85 TPMT_PUBLIC *public,
86 void *ctx)
87 {
88 TSS2_RC r = TSS2_RC_SUCCESS;
89 IFAPI_OBJECT object;
90 FAPI_CONTEXT *context = ctx;
91
92 switch (context->io_state) {
93 statecase(context->io_state, IO_INIT)
94 /* Prepare the loading of the object. */
95 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
96 return_if_error2(r, "Could not open: %s", path);
97 fallthrough;
98
99 statecase(context->io_state, IO_ACTIVE)
100 /* Finalize or retry the reading and check the object type */
101 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
102 &object);
103 return_try_again(r);
104 return_if_error(r, "read_finish failed");
105
106 switch (object.objectType) {
107 case IFAPI_KEY_OBJ:
108 *public = object.misc.key.public.publicArea;
109 break;
110 case IFAPI_EXT_PUB_KEY_OBJ:
111 *public = object.misc.ext_pub_key.public.publicArea;
112 break;
113 default:
114 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Object %s is not a key.",
115 cleanup, path);
116 }
117 break;
118
119 statecasedefault_error(context->state, r, cleanup);
120 }
121
122 cleanup:
123 context->io_state = IO_INIT;
124 ifapi_cleanup_ifapi_object(&object);
125 return r;
126 }
127
128 /** Get TPM name of an object from key keystore.
129 *
130 * @param[in] path The relative path of the object.
131 * @param[out] name The caller allocate public structure.
132 * @param[in,out] ctx The context to access io and keystore module and to store
133 * the io state.
134 * @retval TSS2_RC_SUCCESS on success.
135 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be loaded.
136 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
137 * internal operations or return parameters.
138 * @retval TSS2_FAPI_RC_BAD_TEMPLATE If the loaded template is not
139 * appropriate for this operation.
140 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
141 * the function.
142 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
143 * this function needs to be called again.
144 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
145 * operation already pending.
146 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
147 * during authorization.
148 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
149 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
150 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
151 */
152 TSS2_RC
153 ifapi_get_object_name(
154 const char *path,
155 TPM2B_NAME *name,
156 void *ctx)
157 {
158 TSS2_RC r = TSS2_RC_SUCCESS;
159 IFAPI_OBJECT object;
160 FAPI_CONTEXT *context = ctx;
161
162 switch (context->io_state) {
163 statecase(context->io_state, IO_INIT)
164 /* Prepare the loading of the object. */
165 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
166 return_if_error2(r, "Could not open: %s", path);
167 fallthrough;
168
169 statecase(context->io_state, IO_ACTIVE)
170 /* Finalize or retry the reading and check the object type */
171 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
172 &object);
173 return_try_again(r);
174 return_if_error(r, "read_finish failed");
175
176 switch (object.objectType) {
177 case IFAPI_KEY_OBJ:
178 r = ifapi_get_name(&object.misc.key.public.publicArea,
179 (TPM2B_NAME *)name);
180 break;
181 case IFAPI_EXT_PUB_KEY_OBJ:
182 r = ifapi_get_name(&object.misc.ext_pub_key.public.publicArea,
183 (TPM2B_NAME *)name);
184 break;
185 case IFAPI_NV_OBJ:
186 r = ifapi_nv_get_name(&object.misc.nv.public, name);
187 break;
188 default:
189 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid object %s.",
190 cleanup, path);
191 }
192 goto_if_error(r, "Get object name.", cleanup);
193 break;
194
195 statecasedefault(context->state);
196 }
197
198 cleanup:
199 ifapi_cleanup_ifapi_object(&object);
200 return r;
201 }
202
203 /** Get public data of a NV object from keystore.
204 *
205 * @param[in] path The relative path of the NV object.
206 * @param[out] nv_public The caller allocated public structure.
207 * @param[in,out] ctx The context to access io and keystore module and to store
208 * the io state.
209 * @retval TSS2_RC_SUCCESS on success.
210 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be loaded.
211 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
212 * internal operations or return parameters.
213 * @retval TSS2_FAPI_RC_BAD_TEMPLATE If the loaded template is not
214 * appropriate for this operation.
215 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
216 * the function.
217 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
218 * this function needs to be called again.
219 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
220 * operation already pending.
221 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
222 * during authorization.
223 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
224 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
225 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
226 */
227 TSS2_RC
228 ifapi_get_nv_public(
229 const char *path,
230 TPM2B_NV_PUBLIC *nv_public,
231 void *ctx)
232 {
233 TSS2_RC r = TSS2_RC_SUCCESS;
234 IFAPI_OBJECT object;
235 FAPI_CONTEXT *context = ctx;
236
237 switch (context->io_state) {
238 statecase(context->io_state, IO_INIT)
239 /* Prepare the loading of the NV object. */
240 r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
241 return_if_error2(r, "Could not open: %s", path);
242 fallthrough;
243
244 statecase(context->io_state, IO_ACTIVE)
245 /* Finalize or retry the reading and check the object type */
246 r = ifapi_keystore_load_finish(&context->keystore, &context->io,
247 &object);
248 return_try_again(r);
249 return_if_error(r, "read_finish failed");
250
251 if (object.objectType != IFAPI_NV_OBJ) {
252 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Object %s is not a key.",
253 cleanup, path);
254 }
255
256 *nv_public = object.misc.nv.public;
257 context->io_state = IO_INIT;
258 break;
259
260 statecasedefault(context->state);
261 }
262
263 cleanup:
264 ifapi_cleanup_ifapi_object(&object);
265 return r;
266 }
267
268 /** Read values of PCR registers and clear selection.
269 *
270 * @param[in,out] pcr_select The registers to be read (bank selection from profile).
271 * @param[in,out] pcr_selection The registers to be read (with bank selection).
272 * @param[out] pcr_values The callee-allocated public structure.
273 * @param[in,out] ctx The context to access io and keystore module and to store
274 * the io state.
275 * @retval TSS2_RC_SUCCESS on success.
276 * @retval TSS2_FAPI_RC_BAD_VALUE if the input parameters had inappropriate values.
277 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
278 * complete. Call this function again later.
279 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
280 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
281 * operation already pending.
282 */
283 TSS2_RC
284 ifapi_read_pcr(
285 TPMS_PCR_SELECT *pcr_select,
286 TPML_PCR_SELECTION *pcr_selection,
287 TPML_PCRVALUES **pcr_values,
288 void *ctx)
289 {
290 TSS2_RC r = TSS2_RC_SUCCESS;
291 FAPI_CONTEXT *context = ctx;
292 UINT32 update_counter;
293 TPML_PCR_SELECTION *out_selection = NULL;
294 TPML_PCR_SELECTION *profile_selection;
295 TPML_DIGEST *pcr_digests = NULL;
296 size_t i, pcr, n_pcrs = 0, i_pcr;
297
298 switch (context->io_state) {
299 statecase(context->io_state, IO_INIT)
300 if (pcr_select->sizeofSelect) {
301 if (pcr_selection->count) {
302 /* If pcr_select is used pcr_selection can't be initialized */
303 return_error(TSS2_FAPI_RC_BAD_VALUE,
304 "Policy PCR: pcr_selection can't be used if pcr_selection is used.");
305 }
306 /* Determine hash alg */
307 profile_selection = &context->profiles.default_profile.pcr_selection;
308 for (i = 0; i < profile_selection->count; i++) {
309 for (pcr = 0; pcr < TPM2_MAX_PCRS; pcr++) {
310 uint8_t byte_idx = pcr / 8;
311 uint8_t flag = 1 << (pcr % 8);
312 /* Check whether PCR is used. */
313 if (flag & profile_selection->pcrSelections[i].pcrSelect[byte_idx] &&
314 flag & pcr_select->pcrSelect[byte_idx]) {
315 pcr_selection->pcrSelections[0].hash = profile_selection->pcrSelections[i].hash;
316 }
317 }
318 }
319 if (!pcr_selection->pcrSelections[0].hash) {
320 /* hash for current pcr_select can't be determined */
321 return_error(TSS2_FAPI_RC_BAD_VALUE,
322 "Policy PCR: pcr_select does not match profile.");
323 }
324 /* Only one bank will be used. The hash alg from profile will be used */
325 pcr_selection->count = 1;
326 pcr_selection->pcrSelections[0].sizeofSelect = pcr_select->sizeofSelect;
327 for (i = 0; i < pcr_select->sizeofSelect; i++)
328 pcr_selection->pcrSelections[0].pcrSelect[i] = pcr_select->pcrSelect[i];
329 }
330
331 /* Prepare the PCR Reading. */
332 r = Esys_PCR_Read_Async(context->esys,
333 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
334 pcr_selection);
335 return_if_error(r, "PCR Read");
336 fallthrough;
337
338 statecase(context->io_state, IO_ACTIVE)
339 /* Finalize or retry the reading and check the object type */
340 r = Esys_PCR_Read_Finish(context->esys,
341 &update_counter,
342 &out_selection,
343 &pcr_digests);
344
345 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN)
346 return TSS2_FAPI_RC_TRY_AGAIN;
347
348 return_if_error(r, "PCR_Read_Finish");
349
350 /* Count pcrs */
351 for (i = 0; i < out_selection->count; i++) {
352 for (pcr = 0; pcr < TPM2_MAX_PCRS; pcr++) {
353 uint8_t byte_idx = pcr / 8;
354 uint8_t flag = 1 << (pcr % 8);
355 /* Check whether PCR is used. */
356 if (flag & out_selection->pcrSelections[i].pcrSelect[byte_idx])
357 n_pcrs += 1;
358 }
359 }
360
361 *pcr_values = calloc(1, sizeof(TPML_PCRVALUES) + n_pcrs* sizeof(TPMS_PCRVALUE));
362 goto_if_null2(*pcr_values, "Out of memory.", r, TSS2_FAPI_RC_MEMORY, cleanup);
363
364 /* Initialize digest list with pcr values from TPM */
365 i_pcr = 0;
366 for (i = 0; i < out_selection->count; i++) {
367 for (pcr = 0; pcr < TPM2_MAX_PCRS; pcr++) {
368 uint8_t byte_idx = pcr / 8;
369 uint8_t flag = 1 << (pcr % 8);
370 /* Check whether PCR is used. */
371 if (flag & out_selection->pcrSelections[i].pcrSelect[byte_idx]) {
372 (*pcr_values)->pcrs[i_pcr].pcr = pcr;
373 (*pcr_values)->pcrs[i_pcr].hashAlg = out_selection->pcrSelections[i].hash;
374 memcpy(&(*pcr_values)->pcrs[i_pcr].digest,
375 &pcr_digests->digests[i_pcr].buffer[0],
376 pcr_digests->digests[i_pcr].size);
377 i_pcr += 1;
378 }
379 }
380 }
381
382 context->io_state = IO_INIT;
383 break;
384
385 statecasedefault(context->state);
386 }
387
388 cleanup:
389 SAFE_FREE(out_selection);
390 SAFE_FREE(pcr_digests);
391 return r;
392 }
393
394 /** Callback for authorization of objects used by policy.
395 *
396 * @param[in] name The name of the object to be authorized.
397 * @param[in] object_handle The ESYS handle of the used object.
398 * @param[in] auth_handle will be used for object authorization. For
399 keys it will we equal to the object handle.
400 * @param[out] authSession The session used for object authorization.
401 * @param[in,out] userdata The Fapi context which will be used for keystore
402 * access, and storing the policy execution state.
403 * the io state.
404 * @retval TSS2_RC_SUCCESS on success.
405 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or policy is NULL.
406 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
407 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
408 * complete. Call this function again later.
409 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
410 * operation already pending.
411 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy was not found.
412 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND If a key was not found.
413 * @retval TSS2_FAPI_RC_IO_ERROR If an IO error occurred during reading
414 * a policy or a key.
415 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an error in an used library
416 * occurred.
417 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
418 * the function.
419 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
420 * is not set.
421 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
422 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
423 * was not successful.
424 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
425 */
426 TSS2_RC
427 ifapi_policyeval_cbauth(
428 TPM2B_NAME *name,
429 ESYS_TR *object_handle,
430 ESYS_TR *auth_handle,
431 ESYS_TR *authSession,
432 void *userdata)
433 {
434 TSS2_RC r;
435 FAPI_CONTEXT *fapi_ctx = userdata;
436 IFAPI_POLICY_EXEC_CTX *current_policy;
437 IFAPI_POLICY_EXEC_CB_CTX *cb_ctx;
438 bool next_case;
439
440 return_if_null(fapi_ctx, "Bad user data.", TSS2_FAPI_RC_BAD_REFERENCE);
441 return_if_null(fapi_ctx->policy.policyutil_stack, "Policy not initialized.",
442 TSS2_FAPI_RC_BAD_REFERENCE);
443
444 if (fapi_ctx->policy.util_current_policy) {
445 /* Use the current policy in the policy stack. */
446 current_policy = fapi_ctx->policy.util_current_policy->pol_exec_ctx;
447 } else {
448 /* Start with the bottom of the policy stack */
449 current_policy = fapi_ctx->policy.policyutil_stack->pol_exec_ctx;
450 }
451 cb_ctx = current_policy->app_data;
452
453 do {
454 next_case = false;
455 switch (cb_ctx->cb_state) {
456 statecase(cb_ctx->cb_state, POL_CB_EXECUTE_INIT);
457 cb_ctx->auth_index = ESYS_TR_NONE;
458 /* Search object with name in keystore. */
459 r = ifapi_keystore_search_obj(&fapi_ctx->keystore, &fapi_ctx->io,
460 name,
461 &cb_ctx->object_path);
462 FAPI_SYNC(r, "Search Object", cleanup);
463
464 r = ifapi_keystore_load_async(&fapi_ctx->keystore, &fapi_ctx->io,
465 cb_ctx->object_path);
466 return_if_error2(r, "Could not open: %s", cb_ctx->object_path);
467 SAFE_FREE(cb_ctx->object_path);
468 fallthrough;
469
470 statecase(cb_ctx->cb_state, POL_CB_READ_OBJECT);
471 /* Get object from file */
472 r = ifapi_keystore_load_finish(&fapi_ctx->keystore, &fapi_ctx->io,
473 &cb_ctx->object);
474 return_try_again(r);
475 return_if_error(r, "read_finish failed");
476
477 r = ifapi_initialize_object(fapi_ctx->esys, &cb_ctx->object);
478 goto_if_error(r, "Initialize NV object", cleanup);
479
480 if (cb_ctx->object.objectType == IFAPI_NV_OBJ) {
481 /* NV Authorization */
482
483 cb_ctx->nv_index = cb_ctx->object.handle;
484
485 /* Determine the object used for authorization. */
486 get_nv_auth_object(&cb_ctx->object,
487 cb_ctx->object.handle,
488 &cb_ctx->auth_object,
489 &cb_ctx->auth_index);
490
491 goto_if_error(r, "PolicySecret set authorization", cleanup);
492 cb_ctx->cb_state = POL_CB_AUTHORIZE_OBJECT;
493
494 cb_ctx->auth_object_ptr = &cb_ctx->auth_object;
495 next_case = true;
496 break;
497 } else if (cb_ctx->object.objectType == IFAPI_HIERARCHY_OBJ) {
498 cb_ctx->cb_state = POL_CB_AUTHORIZE_OBJECT;
499 next_case = true;
500 break;
501 } else {
502 cb_ctx->key_handle = cb_ctx->object.handle;
503 cb_ctx->cb_state = POL_CB_LOAD_KEY;
504 }
505 fallthrough;
506
507 statecase(cb_ctx->cb_state, POL_CB_LOAD_KEY);
508 /* Key loading and authorization */
509 r = ifapi_load_key(fapi_ctx, cb_ctx->object_path,
510 &cb_ctx->auth_object_ptr);
511 FAPI_SYNC(r, "Fapi load key.", cleanup);
512
513 cb_ctx->object = *cb_ctx->key_object_ptr;
514 SAFE_FREE(cb_ctx->key_object_ptr);
515 cb_ctx->auth_object_ptr = &cb_ctx->object;
516 fallthrough;
517
518 statecase(cb_ctx->cb_state, POL_CB_AUTHORIZE_OBJECT);
519 r = ifapi_authorize_object(fapi_ctx, cb_ctx->auth_object_ptr, authSession);
520 return_try_again(r);
521 goto_if_error(r, "Authorize object.", cleanup);
522
523 cb_ctx->cb_state = POL_CB_EXECUTE_INIT;
524 break;
525 /* FALLTHRU */
526
527 statecasedefault(cb_ctx->cb_state);
528 }
529 } while (next_case);
530 *object_handle = cb_ctx->object.handle;
531 if (cb_ctx->object.objectType == IFAPI_NV_OBJ)
532 *auth_handle = cb_ctx->auth_index;
533 else
534 *auth_handle = cb_ctx->object.handle;
535
536 if (current_policy->policySessionSav != ESYS_TR_NONE)
537 fapi_ctx->policy.session = current_policy->policySessionSav;
538
539 cleanup:
540 ifapi_cleanup_ifapi_object(&cb_ctx->object);
541 if (current_policy->policySessionSav
542 && current_policy->policySessionSav != ESYS_TR_NONE)
543 fapi_ctx->policy.session = current_policy->policySessionSav;
544 return r;
545 }
546
547 /** Callback for branch selection of policy or.
548 *
549 * @param[in] branches The list of policy branches.
550 * @param[out] branch_idx The index of the selcted branch.
551 * @param[in,out] userdata The Fapi context which will be used for keystore
552 * access, and storing the policy execution state.
553 * the io state.
554 * @retval TSS2_RC_SUCCESS on success.
555 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context is NULL.
556 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if no branch selection callback is
557 * defined. This callback will be needed of or policies which have to be
558 * executed.
559 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the computed branch index
560 * delivered by the callback does not identify a branch.
561 */
562 TSS2_RC
563 ifapi_branch_selection(
564 TPML_POLICYBRANCHES *branches,
565 size_t *branch_idx,
566 void *userdata)
567 {
568 TSS2_RC r;
569 FAPI_CONTEXT *fapi_ctx = userdata;
570 size_t i;
571 const char *names[8];
572
573 return_if_null(fapi_ctx, "Bad user data.", TSS2_FAPI_RC_BAD_REFERENCE);
574
575 if (!fapi_ctx->callbacks.branch) {
576 return_error(TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN,
577 "No branch selection callback");
578 }
579 for (i = 0; i < branches->count; i++)
580 names[i] = branches->authorizations[i].name;
581
582 r = fapi_ctx->callbacks.branch(fapi_ctx, "PolicyOR",
583 &names[0],
584 branches->count,
585 branch_idx,
586 fapi_ctx->callbacks.branchData);
587 return_if_error(r, "policyBranchSelectionCallback");
588
589 if (*branch_idx >= branches->count) {
590 return_error2(TSS2_FAPI_RC_AUTHORIZATION_FAILED, "Invalid branch number.");
591 }
592 return TSS2_RC_SUCCESS;
593 }
594
595 /** Callback for policy action.
596 *
597 * @param[in] action The name of the policy action.
598 * @param[in,out] userdata The Fapi context which will be used for keystore
599 * access, and storing the policy execution state.
600 * the io state.
601 * @retval TSS2_RC_SUCCESS on success.
602 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for branch selection is
603 * not defined. This callback will be needed of or policies have to be
604 * executed.
605 * @retval TSS2_FAPI_RC_BAD_REFERENCE If no user data is passed.
606 */
607 TSS2_RC
608 ifapi_policy_action(
609 const char *action,
610 void *userdata)
611 {
612 TSS2_RC r;
613 FAPI_CONTEXT *fapi_ctx = userdata;
614 return_if_null(fapi_ctx, "Bad user data.", TSS2_FAPI_RC_BAD_REFERENCE);
615
616 if (!fapi_ctx->callbacks.action) {
617 return_error(TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN,
618 "No action callback");
619 }
620 r = fapi_ctx->callbacks.action(fapi_ctx, action,
621 fapi_ctx->callbacks.actionData);
622 return_if_error(r, "ifapi_policy_action callback");
623
624 return TSS2_RC_SUCCESS;
625 }
626
627 /** Callback for signing a byte buffer.
628 *
629 * @param[in] key_pem The pem key used for signing operation.
630 * @param[in] public_key_hint A human readable hint to denote which public
631 * key to use.
632 * @param[in] key_pem_hash_alg The hash alg used for digest computation.
633 * @param[in] buffer the byte array to be signed.
634 * @param[in] buffer_size The size of the buffer to be signed.
635 * @param[out] signature The signature in DER format.
636 * @param[out] signature_size The size of the signature.
637 * @param[in] userdata The user context to retrieve the signing function.
638 * @retval TSS2_RC_SUCCESS on success.
639 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for signing is
640 * not defined.
641 * @retval TSS2_FAPI_RC_BAD_REFERENCE If no user data is passed.
642 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the callback operation is not yet
643 * complete. Call this function again later.
644 */
645 TSS2_RC
646 ifapi_sign_buffer(
647 char *key_pem,
648 char *public_key_hint,
649 TPMI_ALG_HASH key_pem_hash_alg,
650 uint8_t *buffer,
651 size_t buffer_size,
652 uint8_t **signature,
653 size_t *signature_size,
654 void *userdata)
655 {
656 TSS2_RC r;
657 FAPI_CONTEXT *fapi_ctx = userdata;
658
659 return_if_null(fapi_ctx, "Bad user data.", TSS2_FAPI_RC_BAD_REFERENCE);
660
661 if (!fapi_ctx->callbacks.sign) {
662 return_error2(TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN,
663 "No signature callback.");
664 }
665 r = fapi_ctx->callbacks.sign(fapi_ctx, "PolicySigned", key_pem,
666 public_key_hint ? public_key_hint : "",
667 key_pem_hash_alg,
668 buffer, buffer_size,
669 signature, signature_size,
670 fapi_ctx->callbacks.signData);
671 try_again_or_error(r, "Execute policy signature callback.");
672
673 return TSS2_RC_SUCCESS;
674 }
675
676 /** Check whether public data of key is assigned to policy.
677 *
678 * It will be checked whether policy was authorized by abort key with public
679 * data of type TPMT_PUBLIC.
680 *
681 * @param[in] policy The policy to be checked.
682 * @param[in] publicVoid The public information of the key.
683 * @param[in] nameAlgVoid Not used for this compare function.
684 * @param[out] equal Switch whether check was successful.
685 */
686 static TSS2_RC
687 equal_policy_authorization(
688 TPMS_POLICY *policy,
689 void *publicVoid,
690 void *nameAlgVoid,
691 bool *equal)
692 {
693 TPMT_PUBLIC *public = publicVoid;
694 (void)nameAlgVoid;
695 size_t i;
696 TPML_POLICYAUTHORIZATIONS *authorizations = policy->policyAuthorizations;
697
698 *equal = false;
699 if (authorizations) {
700 for (i = 0; i < authorizations->count; i++) {
701 if (ifapi_TPMT_PUBLIC_cmp
702 (public, &authorizations->authorizations[i].key)) {
703 *equal = true;
704 return TSS2_RC_SUCCESS;
705 }
706 }
707 }
708 return TSS2_RC_SUCCESS;
709 }
710
711 /** Check whether policy digest can be found in policy.
712 *
713 * It will be tested whether the policy has been instatiated with the
714 * passed digest.
715 *
716 * @param[in] policy The policy to be checked.
717 * @param[in] authPolicyVoid The digest to be searched.
718 * @param[in] nameAlgVoid The hash algorithm used for the digest computation.
719 * @param[out] equal Switch whether check was successful.
720 */
721 static TSS2_RC
722 compare_policy_digest(
723 TPMS_POLICY *policy,
724 void *authPolicyVoid,
725 void *nameAlgVoid,
726 bool *equal)
727 {
728 TPM2B_DIGEST *authPolicy = authPolicyVoid;
729 TPMI_ALG_HASH *hash_alg_ptr = nameAlgVoid;
730 TPMI_ALG_HASH hash_alg = *hash_alg_ptr;
731 size_t i;
732 TPML_DIGEST_VALUES *digest_values;
733
734 *equal = false;
735
736 digest_values = &policy->policyDigests;
737
738 if (digest_values) {
739 for (i = 0; i < digest_values->count; i++) {
740 if (digest_values->digests[i].hashAlg == hash_alg) {
741 if (memcmp(&digest_values->digests[i].digest,
742 &authPolicy->buffer[0],
743 authPolicy->size))
744 continue;
745 *equal = true;
746 return TSS2_RC_SUCCESS;
747 }
748 }
749 }
750 return TSS2_RC_SUCCESS;
751 }
752
753 /** Search a policy file which fulfills a certain predicate.
754 *
755 * @param[in] context The context for storing the state information of the search
756 process and the keystore paths.
757 * @param[in] compare The function which will be used for comparison.
758 * @param[in] all_objects Switch which determines wheter all policies fulfilling the
759 * the condition will be returned or only the first policy.
760 * @param[in] object1 The first object used for comparison.
761 * @param[in] object2 The second object used for comparison.
762 * @param[out] policy_found The linked list with the policies fulfilling the condition.
763 *
764 * @retval TSS2_RC_SUCCESS on success.
765 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
766 * was not successful.
767 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
768 * this function needs to be called again.
769 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
770 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
771 * the function.
772 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
773 * object store.
774 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
775 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
776 */
777 static TSS2_RC
778 search_policy(
779 FAPI_CONTEXT *context,
780 Policy_Compare_Object compare,
781 bool all_objects,
782 void *object1,
783 void *object2,
784 struct POLICY_LIST **policy_found)
785 {
786 TSS2_RC r = TSS2_RC_SUCCESS;
787 char *path;
788 TPMS_POLICY policy = { 0 };
789 bool found;
790 struct POLICY_LIST *policy_object = NULL;
791 struct POLICY_LIST *second;
792
793 switch (context->fsearch.state) {
794 case FSEARCH_INIT:
795 LOG_DEBUG("** STATE ** FSEARCH_INIT");
796 memset(&context->fsearch, 0, sizeof(IFAPI_FILE_SEARCH_CTX));
797 /* Get the list of all files. */
798 r = ifapi_keystore_list_all(&context->keystore, IFAPI_POLICY_DIR, &context->fsearch.pathlist,
799 &context->fsearch.numPaths);
800 return_if_error(r, "get entities.");
801 context->fsearch.path_idx = context->fsearch.numPaths;
802
803 context->fsearch.state = FSEARCH_OBJECT;
804 /* FALLTHRU */
805
806 case FSEARCH_OBJECT:
807 LOG_DEBUG("** STATE ** FSEARCH_OBJECT");
808
809 /* Test whether all files have been checked. */
810 if (context->fsearch.path_idx == 0) {
811 if (*policy_found) {
812 context->fsearch.state = FSEARCH_INIT;
813 for (size_t i = 0; i < context->fsearch.numPaths; i++) {
814 SAFE_FREE(context->fsearch.pathlist[i]);
815 }
816 SAFE_FREE(context->fsearch.pathlist);
817 return TSS2_RC_SUCCESS;
818 }
819 goto_error(r, TSS2_FAPI_RC_POLICY_UNKNOWN, "Policy not found.", cleanup);
820 }
821 context->fsearch.path_idx -= 1;
822 path = context->fsearch.pathlist[context->fsearch.path_idx];
823 context->fsearch.current_path = path;
824 LOG_DEBUG("Check file: %s %zu", path, context->fsearch.path_idx);
825
826 /* Prepare policy loading. */
827 r = ifapi_policy_store_load_async(&context->pstore, &context->io, path);
828 goto_if_error2(r, "Can't open: %s", cleanup, path);
829
830 context->fsearch.state = FSEARCH_READ;
831 /* FALLTHRU */
832
833 case FSEARCH_READ:
834 LOG_DEBUG("** STATE ** FSEARCH_READ");
835 /* Finalize policy loading if possible. */
836 r = ifapi_policy_store_load_finish(&context->pstore, &context->io, &policy);
837 return_try_again(r);
838 goto_if_error(r, "read_finish failed", cleanup);
839
840 /* Call the passed compare function. */
841 r = compare(&policy, object1, object2, &found);
842 if (found) {
843 LOG_DEBUG("compare true %s",
844 context->fsearch.pathlist[context->fsearch.path_idx]);
845 } else {
846 LOG_DEBUG("compare false %s",
847 context->fsearch.pathlist[context->fsearch.path_idx]);
848 }
849 goto_if_error(r, "Invalid cipher object.", cleanup);
850
851 if (!found) {
852 if (!all_objects && context->fsearch.path_idx == 0) {
853 /* All files checked, but no policy found. */
854 context->fsearch.state = FSEARCH_INIT;
855 ifapi_cleanup_policy(&policy);
856 return TSS2_BASE_RC_POLICY_UNKNOWN;
857 } else {
858 /* Continue search. */
859 context->fsearch.state = FSEARCH_OBJECT;
860 ifapi_cleanup_policy(&policy);
861 return TSS2_FAPI_RC_TRY_AGAIN;
862 }
863 }
864 /* Extend linked list.*/
865 policy_object = calloc(sizeof(struct POLICY_LIST), 1);
866 return_if_null(policy_object, "Out of memory.", TSS2_FAPI_RC_MEMORY);
867
868 strdup_check(policy_object->path, context->fsearch.current_path, r, cleanup);
869 policy_object->policy = policy;
870 if (*policy_found != NULL) {
871 second = *policy_found;
872 policy_object->next = second;
873 }
874 *policy_found = policy_object;
875
876 if (context->fsearch.path_idx == 0) {
877 context->fsearch.state = FSEARCH_INIT;
878 /* Cleanup list of all paths. */
879 for (size_t i = 0; i < context->fsearch.numPaths; i++) {
880 SAFE_FREE(context->fsearch.pathlist[i]);
881 }
882 SAFE_FREE(context->fsearch.pathlist);
883 return TSS2_RC_SUCCESS;
884 }
885
886 if (all_objects) {
887 context->fsearch.state = FSEARCH_OBJECT;
888 return TSS2_FAPI_RC_TRY_AGAIN;
889 }
890
891 break;
892
893 default:
894 context->state = _FAPI_STATE_INTERNALERROR;
895 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid state for load key.", cleanup);
896 }
897 context->fsearch.state = FSEARCH_INIT;
898 for (size_t i = 0; i < context->fsearch.numPaths; i++) {
899 SAFE_FREE(context->fsearch.pathlist[i]);
900 }
901 SAFE_FREE(context->fsearch.pathlist);
902 return TSS2_RC_SUCCESS;
903 cleanup:
904 SAFE_FREE(policy_object);
905 ifapi_cleanup_policy(&policy);
906 for (size_t i = 0; i < context->fsearch.numPaths; i++) {
907 SAFE_FREE(context->fsearch.pathlist[i]);
908 }
909 SAFE_FREE(context->fsearch.pathlist);
910 context->fsearch.state = FSEARCH_INIT;
911 return r;
912 }
913
914 /** Get policy digest for a certain hash alg.
915 *
916 * @param[in] policy The policy with the digest list.
917 * @param[in] hashAlg The hash algorithm used for the digest computation.
918 * @param[out] digest The digest matching hashAlg.
919 * @retval TSS2_RC_SUCCESS on success.
920 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
921 * the function.
922 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
923 */
924 static TSS2_RC
925 get_policy_digest(TPMS_POLICY *policy,
926 TPMI_ALG_HASH hashAlg,
927 TPM2B_DIGEST *digest)
928 {
929 size_t i;
930
931 if (!(digest->size = ifapi_hash_get_digest_size(hashAlg))) {
932 return_error2(TSS2_FAPI_RC_BAD_VALUE,
933 "Unsupported hash algorithm (%" PRIu16 ")", hashAlg);
934 }
935
936 for (i = 0; i < policy->policyDigests.count; i++) {
937 if (policy->policyDigests.digests[i].hashAlg == hashAlg) {
938 memcpy(&digest->buffer[0],
939 &policy->policyDigests.digests[i].digest, digest->size);
940 return TSS2_RC_SUCCESS;
941 }
942 }
943 return TSS2_FAPI_RC_GENERAL_FAILURE;
944 }
945
946 /** Get policy authorization for a certain public key
947 *
948 * @param[in] policy The policy with the authorization.
949 * @param[in] public The public data of the key.
950 * @param[out] signature The signature found in the authorization list.
951 * @retval TSS2_RC_SUCCESS on success.
952 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
953 */
954 static TSS2_RC
955 get_policy_signature(
956 TPMS_POLICY *policy,
957 TPMT_PUBLIC *public,
958 TPMT_SIGNATURE *signature)
959 {
960 size_t i;
961
962 for (i = 0; i < policy->policyAuthorizations->count; i++) {
963 if (ifapi_TPMT_PUBLIC_cmp(public,
964 &policy->policyAuthorizations->authorizations[i].key)) {
965 *signature = policy->policyAuthorizations->authorizations[i].signature;
966 return TSS2_RC_SUCCESS;
967 }
968 }
969 /* Appropriate authorization should always exist */
970 return TSS2_FAPI_RC_GENERAL_FAILURE;
971 }
972
973 /** Cleanup a linked list of policies.
974 *
975 * @param[in] The linked list.
976 */
977 static void
978 cleanup_policy_list(struct POLICY_LIST * list) {
979 if (list) {
980 struct POLICY_LIST * branch = list;
981 while (branch) {
982 struct POLICY_LIST *next = branch->next;
983 /* Cleanup the policy stored in the list. */
984 ifapi_cleanup_policy(&branch->policy);
985 SAFE_FREE(branch->path);
986 SAFE_FREE(branch);
987 branch = next;
988 }
989 }
990 }
991
992 /** Callback for retrieving, selecting and execute a authorized policy.
993 *
994 * All policies authorized by a certain key will be retrieved and one policy
995 * will be selected via a branch selection callback.
996 *
997 * @param[in] key_public the public data of the key which was used for policy
998 * authorization.
999 * @param[in] hash_alg The hash algorithm used for policy computation.
1000 * @param[out] digest The policy digest of the authorized policy.
1001 * @param[out] signature The signature produced during policy authorization.
1002 * @param[in] userdata The user context to retrieve the policy.
1003 * @retval TSS2_RC_SUCCESS on success.
1004 * @retval TSS2_FAPI_RC_MEMORY: if it's not possible to allocate enough memory.
1005 * @retval TSS2_FAPI_RC_BAD_REFERENCE If no user data id passed or context stack
1006 * is not initialized.
1007 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
1008 * store.
1009 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
1010 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest
1011 * was not successful.
1012 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
1013 * execution fails.
1014 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1015 * is not set.
1016 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1017 * the function.
1018 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1019 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1020 * this function needs to be called again.
1021 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1022 * operation already pending.
1023 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1024 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1025 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1026 */
1027 TSS2_RC
1028 ifapi_exec_auth_policy(
1029 TPMT_PUBLIC *key_public,
1030 TPMI_ALG_HASH hash_alg,
1031 TPM2B_DIGEST *digest,
1032 TPMT_SIGNATURE *signature,
1033 void *userdata)
1034 {
1035 TSS2_RC r;
1036 FAPI_CONTEXT *fapi_ctx = userdata;
1037 IFAPI_POLICY_EXEC_CTX *current_policy;
1038 IFAPI_POLICY_EXEC_CB_CTX *cb_ctx;
1039 size_t n, i;
1040 struct POLICY_LIST *branch;
1041 const char **names = NULL;
1042 size_t branch_idx;
1043 bool policy_set = false;
1044
1045 return_if_null(fapi_ctx, "Bad user data.", TSS2_FAPI_RC_BAD_REFERENCE);
1046 return_if_null(fapi_ctx->policy.policyutil_stack, "Policy not initialized.",
1047 TSS2_FAPI_RC_BAD_REFERENCE);
1048
1049 if (fapi_ctx->policy.util_current_policy) {
1050 /* Use the current policy in the policy stack. */
1051 current_policy = fapi_ctx->policy.util_current_policy->pol_exec_ctx;
1052 } else {
1053 /* Start with the bottom of the policy stack */
1054 current_policy = fapi_ctx->policy.policyutil_stack->pol_exec_ctx;
1055 }
1056 cb_ctx = current_policy->app_data;
1057
1058 switch (cb_ctx->cb_state) {
1059 statecase(cb_ctx->cb_state, POL_CB_EXECUTE_INIT)
1060 current_policy->object_handle = ESYS_TR_NONE;
1061 current_policy->policy_list = NULL;
1062 fallthrough;
1063
1064 statecase(cb_ctx->cb_state, POL_CB_SEARCH_POLICY)
1065 r = search_policy(fapi_ctx,
1066 equal_policy_authorization, true,
1067 key_public, NULL,
1068 &current_policy->policy_list);
1069 FAPI_SYNC(r, "Search policy", cleanup);
1070
1071 if (current_policy->policy_list->next) {
1072 /* More than one policy has to be selected via
1073 callback */
1074 if (!fapi_ctx->callbacks.branch) {
1075 return_error(TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN,
1076 "No branch selection callback");
1077 }
1078 n = 1;
1079
1080 /* Count policies */
1081 for (branch = current_policy->policy_list; branch->next;
1082 branch = branch->next)
1083 n += 1;
1084 names = malloc(sizeof(char *) * n);
1085 return_if_null(names, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1086 i = 0;
1087 branch = current_policy->policy_list;
1088 /* Compute name list for slectiion callback. */
1089 do {
1090 names[i] = branch->path;
1091 i += 1;
1092 branch = branch->next;
1093 } while (branch);
1094
1095 /* Policy selection */
1096 r = fapi_ctx->callbacks.branch(fapi_ctx, "PolicyAuthorize",
1097 &names[0], n, &branch_idx,
1098 fapi_ctx->callbacks.branchData);
1099 goto_if_error(r, "policyBranchSelectionCallback", cleanup);
1100
1101 if (branch_idx >= n) {
1102 goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid branch number.",
1103 cleanup);
1104 }
1105 /* Get policy from policy list */
1106 n = 0;
1107 branch = current_policy->policy_list;
1108 do {
1109 if (n == branch_idx) {
1110 cb_ctx->policy = &branch->policy;
1111 policy_set = true;
1112 break;
1113 }
1114 n += 1;
1115 branch = branch->next;
1116 } while (branch);
1117
1118 } else {
1119 /* Only one policy found. */
1120 cb_ctx->policy = &current_policy->policy_list->policy;
1121 policy_set = true;
1122 }
1123 if (!policy_set) {
1124 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Policy could not be set.",
1125 cleanup);
1126 }
1127 /* Prepare policy execution */
1128 r = ifapi_policyutil_execute_prepare(fapi_ctx, current_policy->hash_alg,
1129 cb_ctx->policy);
1130 /* Next state will switch from prev context to next context. */
1131 goto_if_error(r, "Prepare policy execution.", cleanup);
1132 fallthrough;
1133
1134 statecase(cb_ctx->cb_state, POL_CB_EXECUTE_SUB_POLICY)
1135 ESYS_TR session = current_policy->session;
1136 r = ifapi_policyutil_execute(fapi_ctx, &session);
1137 if (r == TSS2_FAPI_RC_TRY_AGAIN){
1138 SAFE_FREE(names);
1139 return r;
1140 }
1141
1142 goto_if_error(r, "Execute policy.", cleanup);
1143
1144 r = get_policy_signature(cb_ctx->policy, key_public,
1145 signature);
1146 goto_if_error(r, "Get authorization", cleanup);
1147
1148 r = get_policy_digest(cb_ctx->policy, hash_alg, digest);
1149 goto_if_error(r, "Get authorization", cleanup);
1150 cb_ctx->cb_state = POL_CB_EXECUTE_INIT;
1151 break;
1152
1153 statecasedefault_error(cb_ctx->state, r, cleanup);
1154 }
1155 cleanup:
1156 SAFE_FREE(names);
1157 cleanup_policy_list(current_policy->policy_list);
1158 return r;
1159 }
1160
1161 /** Callback for executing a policy identified by a digest stored in a nv object.
1162 *
1163 * @param[in] nv_public the public data of the nv object which stores the digest
1164 * of the authorized policy.
1165 * @param[in] hash_alg The hash algorithm used for policy computation.
1166 * @param[in] userdata The user context to retrieve the policy.
1167 * @retval TSS2_RC_SUCCESS on success.
1168 * @retval TSS2_FAPI_RC_MEMORY: if it's not possible to allocate enough memory.
1169 * @retval TSS2_FAPI_RC_BAD_REFERENCE If no user data id passed or context stack
1170 * is not initialized.
1171 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
1172 * store.
1173 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
1174 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
1175 * not successful.
1176 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
1177 * execution fails.
1178 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1179 * the function.
1180 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1181 * this function needs to be called again.
1182 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1183 * operation already pending.
1184 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1185 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1186 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1187 * is not set.
1188 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1189 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1190 */
1191 TSS2_RC
1192 ifapi_exec_auth_nv_policy(
1193 TPM2B_NV_PUBLIC *nv_public,
1194 TPMI_ALG_HASH hash_alg,
1195 void *userdata)
1196 {
1197 TSS2_RC r;
1198 TPM2B_MAX_NV_BUFFER *aux_data;
1199 FAPI_CONTEXT *fapi_ctx = userdata;
1200 IFAPI_POLICY_EXEC_CTX *current_policy;
1201 IFAPI_POLICY_EXEC_CB_CTX *cb_ctx;
1202 char *nv_path = NULL;
1203 ESYS_CONTEXT *esys_ctx;
1204 size_t digest_size, offset;
1205 TPMT_HA nv_policy;
1206
1207 return_if_null(fapi_ctx, "Bad user data.", TSS2_FAPI_RC_BAD_REFERENCE);
1208 return_if_null(fapi_ctx->policy.policyutil_stack, "Policy not initialized.",
1209 TSS2_FAPI_RC_BAD_REFERENCE);
1210
1211 if (fapi_ctx->policy.util_current_policy) {
1212 /* Use the current policy in the policy stack. */
1213 current_policy = fapi_ctx->policy.util_current_policy->pol_exec_ctx;
1214 } else {
1215 /* Start with the bottom of the policy stack */
1216 current_policy = fapi_ctx->policy.policyutil_stack->pol_exec_ctx;
1217 }
1218 cb_ctx = current_policy->app_data;
1219 esys_ctx = fapi_ctx->esys;
1220
1221 if (!(digest_size = ifapi_hash_get_digest_size(hash_alg))) {
1222 return_error2(TSS2_FAPI_RC_BAD_VALUE,
1223 "Unsupported hash algorithm (%" PRIu16 ")", hash_alg);
1224 }
1225
1226 switch (cb_ctx->cb_state) {
1227 statecase(cb_ctx->cb_state, POL_CB_EXECUTE_INIT)
1228 /* Search a NV object with a certain NV indext stored in nv_public. */
1229 r = ifapi_keystore_search_nv_obj(&fapi_ctx->keystore, &fapi_ctx->io,
1230 nv_public, &nv_path);
1231 FAPI_SYNC(r, "Search Object", cleanup);
1232
1233 r = ifapi_keystore_load_async(&fapi_ctx->keystore, &fapi_ctx->io, nv_path);
1234 SAFE_FREE(nv_path);
1235 return_if_error2(r, "Could not open: %s", nv_path);
1236
1237 fallthrough;
1238
1239 statecase(cb_ctx->cb_state, POL_CB_NV_READ)
1240 /* Get object from file */
1241 r = ifapi_keystore_load_finish(&fapi_ctx->keystore, &fapi_ctx->io,
1242 &cb_ctx->object);
1243 return_try_again(r);
1244 return_if_error(r, "read_finish failed");
1245
1246 r = ifapi_initialize_object(esys_ctx, &cb_ctx->object);
1247 goto_if_error(r, "Initialize NV object", cleanup);
1248
1249 current_policy->nv_index = cb_ctx->object.handle;
1250 ifapi_cleanup_ifapi_object(&cb_ctx->object);
1251 get_nv_auth_object(&cb_ctx->object,
1252 current_policy->nv_index,
1253 &current_policy->auth_object,
1254 &current_policy->auth_handle);
1255 fallthrough;
1256
1257 statecase(cb_ctx->cb_state, POL_CB_AUTHORIZE_OBJECT)
1258 /* Authorize the NV object with the corresponding auth object. */
1259 r = ifapi_authorize_object(fapi_ctx, &cb_ctx->auth_object, &cb_ctx->session);
1260 return_try_again(r);
1261 goto_if_error(r, "Authorize object.", cleanup);
1262
1263 /* Prepare the reading of the NV index from TPM. */
1264 r = Esys_NV_Read_Async(esys_ctx,
1265 current_policy->auth_handle, current_policy->nv_index,
1266 cb_ctx->session, ESYS_TR_NONE, ESYS_TR_NONE,
1267 sizeof(TPMI_ALG_HASH) + digest_size, 0);
1268 goto_if_error(r, "Unmarshal policy", cleanup);
1269 fallthrough;
1270
1271 statecase(cb_ctx->cb_state, POL_CB_READ_NV_POLICY)
1272 /* Finalize the reading. */
1273 r = Esys_NV_Read_Finish(esys_ctx, &aux_data);
1274 try_again_or_error_goto(r, "NV read", cleanup);
1275
1276 offset = 0;
1277 r = Tss2_MU_TPMT_HA_Unmarshal(&aux_data->buffer[0], aux_data->size,
1278 &offset, &nv_policy);
1279 Esys_Free(aux_data);
1280 goto_if_error(r, "Unmarshal policy", cleanup);
1281
1282 cb_ctx->policy_digest.size = digest_size;
1283 memcpy(&cb_ctx->policy_digest.buffer[0], &nv_policy.digest, digest_size);
1284 fallthrough;
1285
1286 statecase(cb_ctx->cb_state, POL_CB_SEARCH_POLICY)
1287 /* Search policy appropriate in object store */
1288 r = search_policy(fapi_ctx, compare_policy_digest, false,
1289 &cb_ctx->policy_digest, &hash_alg,
1290 &current_policy->policy_list);
1291 FAPI_SYNC(r, "Search policy", cleanup);
1292
1293 if (!current_policy->policy_list) {
1294 goto_error(r, TSS2_FAPI_RC_POLICY_UNKNOWN, "Policy not found", cleanup);
1295 }
1296 /* Prepare policy execution */
1297 r = ifapi_policyutil_execute_prepare(fapi_ctx, current_policy->hash_alg,
1298 &current_policy->policy_list->policy);
1299 return_if_error(r, "Prepare policy execution.");
1300 fallthrough;
1301
1302 statecase(cb_ctx->cb_state, POL_CB_EXECUTE_SUB_POLICY)
1303 ESYS_TR session = current_policy->session;
1304 r = ifapi_policyutil_execute(fapi_ctx, &session);
1305 if (r == TSS2_FAPI_RC_TRY_AGAIN)
1306 return r;
1307
1308 goto_if_error(r, "Execute policy.", cleanup);
1309 cb_ctx->cb_state = POL_CB_EXECUTE_INIT;
1310 break;
1311
1312 statecasedefault_error(cb_ctx->state, r, cleanup);
1313 }
1314 cleanup:
1315 cleanup_policy_list(current_policy->policy_list);
1316 SAFE_FREE(nv_path);
1317 return r;
1318
1319 }
1320
1321 /** Callback for getting the name of a key to be duplicated.
1322 *
1323 * @param[out] name the name of the object to be duplicated.
1324 * @param[in] userdata The user context to retrieve the key.
1325 * @retval TSS2_RC_SUCCESS on success.
1326 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if the context is not passed or the
1327 * object to be duplicated is not set.
1328 */
1329 TSS2_RC
1330 ifapi_get_duplicate_name(
1331 TPM2B_NAME *name,
1332 void *userdata)
1333 {
1334 FAPI_CONTEXT *fapi_ctx = userdata;
1335
1336 return_if_null(fapi_ctx, "Bad user data.", TSS2_FAPI_RC_BAD_REFERENCE);
1337 return_if_null(fapi_ctx->duplicate_key, "Object for duplication no set.",
1338 TSS2_FAPI_RC_BAD_REFERENCE);
1339 *name = fapi_ctx->duplicate_key->misc.key.name;
1340 return TSS2_RC_SUCCESS;
1341 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef FAPI_POLICY_CALLBACKS_H
6 #define FAPI_POLICY_CALLBACKS_H
7
8
9 /** The states for policy execution callbacks */
10 enum IFAPI_STATE_POL_CB_EXCECUTE {
11 POL_CB_EXECUTE_INIT = 0,
12 POL_CB_LOAD_KEY,
13 POL_CB_SEARCH_POLICY,
14 POL_CB_EXECUTE_SUB_POLICY,
15 POL_CB_NV_READ,
16 POL_CB_READ_NV_POLICY,
17 POL_CB_READ_OBJECT,
18 POL_CB_AUTHORIZE_OBJECT
19 };
20
21 /** The context of the policy execution */
22 typedef struct {
23 enum IFAPI_STATE_POL_CB_EXCECUTE cb_state;
24 /**< The execution state of the current policy callback */
25 char*object_path; /**< The pathname determined by object search */
26 IFAPI_OBJECT object; /**< Object to be authorized */
27 ESYS_TR key_handle; /**< Handle of a used key */
28 ESYS_TR nv_index; /**< Index of nv object storing a policy */
29 ESYS_TR auth_index; /**< Index of authorization object */
30 IFAPI_OBJECT auth_object; /**< FAPI auth object needed for authorization */
31 IFAPI_OBJECT *key_object_ptr;
32 IFAPI_OBJECT *auth_object_ptr;
33 IFAPI_NV_Cmds nv_cmd_state;
34 IFAPI_NV_Cmds nv_cmd_state_sav; /**< backup for state of fapi nv commands */
35 TPM2B_DIGEST policy_digest;
36 ESYS_TR session;
37 TPMS_POLICY *policy;
38 } IFAPI_POLICY_EXEC_CB_CTX;
39
40 TSS2_RC
41 ifapi_get_key_public(
42 const char *path,
43 TPMT_PUBLIC *public,
44 void *context);
45
46 TSS2_RC
47 ifapi_get_object_name(
48 const char *path,
49 TPM2B_NAME *name,
50 void *context);
51
52 TSS2_RC
53 ifapi_get_nv_public(
54 const char *path,
55 TPM2B_NV_PUBLIC *nv_public,
56 void *context);
57
58 TSS2_RC
59 ifapi_read_pcr(
60 TPMS_PCR_SELECT *pcr_select,
61 TPML_PCR_SELECTION *pcr_selection,
62 TPML_PCRVALUES **pcr_values,
63 void *ctx);
64
65 TSS2_RC
66 ifapi_policyeval_cbauth(
67 TPM2B_NAME *name,
68 ESYS_TR *object_handle,
69 ESYS_TR *auth_handle,
70 ESYS_TR *authSession,
71 void *userdata);
72
73 TSS2_RC
74 ifapi_branch_selection(
75 TPML_POLICYBRANCHES *branches,
76 size_t *branch_idx,
77 void *userdata);
78
79 TSS2_RC
80 ifapi_sign_buffer(
81 char *key_pem,
82 char *public_key_hint,
83 TPMI_ALG_HASH key_pem_hash_alg,
84 uint8_t *buffer,
85 size_t buffer_size,
86 uint8_t **signature,
87 size_t *signature_size,
88 void *userdata);
89
90 TSS2_RC
91 ifapi_exec_auth_policy(
92 TPMT_PUBLIC *key_public,
93 TPMI_ALG_HASH hash_alg,
94 TPM2B_DIGEST *digest,
95 TPMT_SIGNATURE *signature,
96 void *userdata);
97
98 TSS2_RC
99 ifapi_exec_auth_nv_policy(
100 TPM2B_NV_PUBLIC *nv_public,
101 TPMI_ALG_HASH hash_alg,
102 void *userdata);
103
104 TSS2_RC
105 ifapi_get_duplicate_name(
106 TPM2B_NAME *name,
107 void *userdata);
108
109 TSS2_RC
110 ifapi_policy_action(
111 const char *action,
112 void *userdata);
113
114 #endif /* FAPI_POLICY_CALLBACKS_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "tss2_mu.h"
14 #include "fapi_util.h"
15 #include "fapi_crypto.h"
16 //#include "fapi_policy.h"
17 #include "ifapi_policy_execute.h"
18 #include "ifapi_helpers.h"
19 #include "ifapi_json_deserialize.h"
20 #include "tpm_json_deserialize.h"
21 #include "ifapi_policy_callbacks.h"
22 #define LOGMODULE fapi
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 /** Copy the policy digests from a branch list to a digest list.
27 *
28 * @param[in] branches The list of policy branches.
29 * @param[in] current_hash_alg The hash algorithm used for computation.
30 * @param[out] digest_list The list of policies computed for every branch.
31 * @retval TSS2_RC_SUCCESS on success.
32 * @retval TSS2_FAPI_RC_BAD_VALUE If no appropriate digest was found in
33 * the branch list.
34 */
35 static TSS2_RC
36 compute_or_digest_list(
37 TPML_POLICYBRANCHES *branches,
38 TPMI_ALG_HASH current_hash_alg,
39 TPML_DIGEST *digest_list)
40 {
41 size_t i;
42 size_t digest_idx, hash_size;
43 bool digest_found = false;
44
45 if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
46 return_error2(TSS2_FAPI_RC_BAD_VALUE,
47 "Unsupported hash algorithm (%" PRIu16 ")",
48 current_hash_alg);
49 }
50 /* Determine digest values with appropriate hash alg */
51 TPML_DIGEST_VALUES *branch_digests = &branches->authorizations[0].policyDigests;
52 for (i = 0; i < branch_digests->count; i++) {
53 if (branch_digests->digests[i].hashAlg == current_hash_alg) {
54 digest_idx = i;
55 digest_found = true;
56 break;
57 }
58 }
59 if (!digest_found) {
60 return_error(TSS2_FAPI_RC_BAD_VALUE, "No digest found for hash alg");
61 }
62
63 digest_list->count = branches->count;
64 for (i = 0; i < branches->count; i++) {
65 if (i > 7) {
66 return_error(TSS2_FAPI_RC_BAD_VALUE, "Too much or branches.");
67 }
68 digest_list->digests[i].size = hash_size;
69 memcpy(&digest_list->digests[i].buffer[0],
70 &branches->authorizations[i].policyDigests.
71 digests[digest_idx].digest, hash_size);
72 LOGBLOB_DEBUG(&digest_list->digests[i].buffer[0],
73 digest_list->digests[i].size, "Compute digest list");
74 }
75 return TSS2_RC_SUCCESS;
76 }
77
78 /** Add a new authorization to a policy.
79 *
80 * The the signed hash computed from the policy digest and the policyRef together with
81 * the public key of the key used for signing will be stored in the policy.
82 *
83 * @param[in,out] policy The policy to be authorized.
84 * @param[in] authorization The structure with the signature, the policyRef and
85 * the public key.
86 *
87 * @retval TSS2_RC_SUCCESS on success.
88 * @retval TSS2_FAPI_RC_MEMORY If the memory for the authorization list cannot be
89 * allocated.
90 */
91 TSS2_RC
92 ifapi_extend_authorization(
93 TPMS_POLICY *policy,
94 TPMS_POLICYAUTHORIZATION *authorization)
95 {
96 TPML_POLICYAUTHORIZATIONS *save = NULL;
97 size_t n = 0;
98 size_t i;
99
100 if (policy->policyAuthorizations) {
101 /* Extend old authorizations */
102 n = policy->policyAuthorizations->count;
103 save = policy->policyAuthorizations;
104 policy->policyAuthorizations =
105 malloc((n + 1) * sizeof(TPMS_POLICYAUTHORIZATION)
106 + sizeof(TPML_POLICYAUTHORIZATIONS));
107 return_if_null(policy->policyAuthorizations->authorizations,
108 "Out of memory.", TSS2_FAPI_RC_MEMORY);
109
110 for (i = 0; i < n; i++)
111 policy->policyAuthorizations->authorizations[i] =
112 save->authorizations[i];
113 policy->policyAuthorizations->authorizations[n] = *authorization;
114 policy->policyAuthorizations->count = n + 1;
115 SAFE_FREE(save);
116 } else {
117 /* No old authorizations exits */
118 policy->policyAuthorizations = malloc(sizeof(TPMS_POLICYAUTHORIZATION)
119 + sizeof(TPML_POLICYAUTHORIZATIONS));
120 return_if_null(policy->policyAuthorizations->authorizations,
121 "Out of memory.", TSS2_FAPI_RC_MEMORY);
122
123 policy->policyAuthorizations->count = 1;
124 policy->policyAuthorizations->authorizations[0] = *authorization;
125 }
126 return TSS2_RC_SUCCESS;
127 }
128 /** Compute the index for the current digest list and clear the digest.
129 *
130 * The list entry with the appropriate hash algorithm will be searched.
131 * The found digest will be set to zero.
132 *
133 * @param[in,out] digest_values The list of policy digests and corresponding
134 * hash algorithms.
135 * @param[in] hashAlg The hash algorithm to be searched.
136 * @param[out] idx The index of the found digest.
137 * @retval TSS2_RC_SUCCESS on success.
138 * @retval TSS2_FAPI_RC_BAD_VALUE If no appropriate digest was found in
139 * the digest list.
140 */
141 TSS2_RC
142 get_policy_digest_idx(TPML_DIGEST_VALUES *digest_values, TPMI_ALG_HASH hashAlg,
143 size_t *idx)
144 {
145 size_t i;
146 for (i = 0; i < digest_values->count; i++) {
147 /* Check whether current hashAlg is appropriate. */
148 if (digest_values->digests[i].hashAlg == hashAlg) {
149 *idx = i;
150 return TSS2_RC_SUCCESS;
151 }
152 }
153
154 if (i >= TPM2_NUM_PCR_BANKS) {
155 return_error(TSS2_FAPI_RC_BAD_VALUE, "Table overflow");
156 }
157 digest_values->digests[i].hashAlg = hashAlg;
158 memset(&digest_values->digests[i].digest, 0, sizeof(TPMU_HA));
159 *idx = i;
160 digest_values->count += 1;
161 return TSS2_RC_SUCCESS;
162 }
163
164 /** Execute policy PCR.
165 *
166 * This command is used to cause conditional gating of a policy based on PCR.
167 *
168 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
169 * policy command.
170 * @param[in,out] policy The PCR policy which will be executed. The policy
171 * digest will be added to the policy.
172 * @param[in] current_hash_alg The hash algorithm wich will be used for
173 * policy computation.
174 * @param[in,out] current_policy The policy context which stores the state
175 * of the policy execution.
176 * @retval TSS2_RC_SUCCESS on success.
177 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
178 * this function needs to be called again.
179 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
180 * operation already pending.
181 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
182 */
183 static TSS2_RC
184 execute_policy_pcr(
185 ESYS_CONTEXT *esys_ctx,
186 TPMS_POLICYPCR *policy,
187 TPMI_ALG_HASH current_hash_alg,
188 IFAPI_POLICY_EXEC_CTX *current_policy)
189 {
190 TSS2_RC r = TSS2_RC_SUCCESS;
191 TPML_PCR_SELECTION pcr_selection;
192 TPM2B_DIGEST pcr_digest;
193
194 LOG_TRACE("call");
195
196 switch (current_policy->state) {
197 statecase(current_policy->state, POLICY_EXECUTE_INIT)
198 /* Compute PCR selection and pcr digest */
199 r = ifapi_compute_policy_digest(policy->pcrs, &pcr_selection,
200 current_hash_alg, &pcr_digest);
201 return_if_error(r, "Compute policy digest and selection.");
202
203 LOGBLOB_DEBUG(&pcr_digest.buffer[0], pcr_digest.size, "PCR Digest");
204
205 /* Prepare the policy execution. */
206 r = Esys_PolicyPCR_Async(esys_ctx,
207 current_policy->session,
208 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
209 &pcr_digest, &pcr_selection);
210 return_if_error(r, "Execute PolicyPCR.");
211 fallthrough;
212
213 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
214 /* Finalize the policy execution if possible. */
215 r = Esys_PolicyPCR_Finish(esys_ctx);
216 try_again_or_error(r, "Execute PolicyPCR_Finish.");
217
218 current_policy->state = POLICY_EXECUTE_INIT;
219 return r;
220
221 statecasedefault(current_policy->state);
222 }
223 return r;
224 }
225
226 /** Execute policy duplicate.
227 *
228 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
229 * policy command.
230 * @param[in,out] policy The duplicate policy which will be executed. The policy
231 * digest will be added to the policy.
232 * @param[in] current_hash_alg The hash algorithm wich will be used for
233 * policy computation.
234 * @param[in,out] current_policy The policy context which stores the state
235 * of the policy execution.
236 * @retval TSS2_RC_SUCCESS on success.
237 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
238 * this function needs to be called again.
239 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
240 * operation already pending.
241 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
242 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
243 */
244 static TSS2_RC
245 execute_policy_duplicate(
246 ESYS_CONTEXT *esys_ctx,
247 TPMS_POLICYDUPLICATIONSELECT *policy,
248 IFAPI_POLICY_EXEC_CTX *current_policy)
249 {
250 TSS2_RC r = TSS2_RC_SUCCESS;
251
252 LOG_TRACE("call");
253
254 switch (current_policy->state) {
255 statecase(current_policy->state, POLICY_EXECUTE_INIT)
256 ifapi_policyeval_EXEC_CB *cb = &current_policy->callbacks;
257 r = cb->cbdup(&policy->objectName, cb->cbdup_userdata);
258 return_if_error(r, "Get name for policy duplicate select.");
259
260 /* Prepare the policy execution. */
261 r = Esys_PolicyDuplicationSelect_Async(esys_ctx,
262 current_policy->session,
263 ESYS_TR_NONE, ESYS_TR_NONE,
264 ESYS_TR_NONE,
265 &policy->objectName,
266 &policy->newParentName,
267 policy->includeObject);
268 return_if_error(r, "Execute PolicyDuplicatonSelect_Async.");
269 fallthrough;
270
271 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
272 /* Finalize the policy execution if possible. */
273 r = Esys_PolicyDuplicationSelect_Finish(esys_ctx);
274 try_again_or_error(r, "Execute PolicyDuplicationselect_Finish.");
275
276 current_policy->state = POLICY_EXECUTE_INIT;
277 return r;
278
279 statecasedefault(current_policy->state);
280 }
281 return r;
282 }
283
284 /** Execute policy NV.
285 *
286 * A policy based on the contents of an NV Index will be executed. The
287 * NV authorization is done by a callback. For an example callback
288 * implementation see ifapi_policyeval_cbauth()
289 *
290 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
291 * policy command.
292 * @param[in,out] policy The NV policy which will be executed. The policy
293 * digest will be added to the policy.
294 * @param[in] current_hash_alg The hash algorithm wich will be used for
295 * policy computation.
296 * @param[in,out] current_policy The policy context which stores the state
297 * of the policy execution.
298 * @retval TSS2_RC_SUCCESS on success.
299 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
300 * this function needs to be called again.
301 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
302 * operation already pending.
303 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
304 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
305 */
306 static TSS2_RC
307 execute_policy_nv(
308 ESYS_CONTEXT *esys_ctx,
309 TPMS_POLICYNV *policy,
310 IFAPI_POLICY_EXEC_CTX *current_policy)
311 {
312 TSS2_RC r = TSS2_RC_SUCCESS;
313
314 LOG_TRACE("call");
315
316 switch (current_policy->state) {
317 statecase(current_policy->state, POLICY_EXECUTE_INIT)
318 r = ifapi_nv_get_name(&policy->nvPublic, &current_policy->name);
319 return_if_error(r, "Compute NV name");
320 fallthrough;
321
322 statecase(current_policy->state, POLICY_AUTH_CALLBACK)
323 ifapi_policyeval_EXEC_CB *cb = &current_policy->callbacks;
324
325 /* Authorize NV object. */
326 r = cb->cbauth(&current_policy->name,
327 &current_policy->object_handle,
328 &current_policy->auth_handle,
329 &current_policy->auth_session, cb->cbauth_userdata);
330 return_try_again(r);
331 return_if_error(r, "Execute authorized policy.");
332
333 /* Prepare the policy execution. */
334 r = Esys_PolicyNV_Async(esys_ctx,
335 current_policy->object_handle,
336 current_policy->auth_handle,
337 current_policy->session,
338 current_policy->auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
339 &policy->operandB, policy->offset,
340 policy->operation);
341 return_if_error(r, "Execute PolicyNV_Async.");
342 fallthrough;
343
344 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
345 /* Finalize the policy execution if possible. */
346 r = Esys_PolicyNV_Finish(esys_ctx);
347 try_again_or_error(r, "Execute PolicyNV_Finish.");
348
349 current_policy->state = POLICY_EXECUTE_INIT;
350 return r;
351
352 statecasedefault(current_policy->state);
353 }
354 return r;
355 }
356
357 /** Execute policy for signature based authorization.
358 *
359 * A signed authorization is included in this policy. The authorization hash
360 * of the policy data will be signed via a callback. For an example callback
361 * implementation see ifapi_sign_buffer()
362 *
363 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
364 * policy command.
365 * @param[in,out] policy The policy to be signed which will be executed. The policy
366 * digest will be added to the policy.
367 * @param[in] current_hash_alg The hash algorithm wich will be used for
368 * policy computation.
369 * @param[in,out] current_policy The policy context which stores the state
370 * of the policy execution.
371 * @retval TSS2_RC_SUCCESS on success.
372 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
373 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
374 * this function needs to be called again.
375 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
376 * operation already pending.
377 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
378 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
379 * is not set.
380 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
381 */
382 static TSS2_RC
383 execute_policy_signed(
384 ESYS_CONTEXT *esys_ctx,
385 TPMS_POLICYSIGNED *policy,
386 IFAPI_POLICY_EXEC_CTX *current_policy)
387 {
388 TSS2_RC r = TSS2_RC_SUCCESS;
389 size_t offset = 0;
390 //TPMT_SIGNATURE signature_tpm;
391 size_t signature_size;
392 uint8_t *signature_ossl = NULL;
393
394 LOG_TRACE("call");
395
396 switch (current_policy->state) {
397 statecase(current_policy->state, POLICY_EXECUTE_INIT);
398 current_policy->pem_key = NULL;
399 current_policy->object_handle = ESYS_TR_NONE;
400 current_policy->buffer_size = sizeof(INT32) + sizeof(TPM2B_NONCE)
401 + policy->cpHashA.size + policy->policyRef.size;
402 current_policy->buffer = malloc(current_policy->buffer_size);
403 return_if_null(current_policy->buffer, "Out of memory.", TSS2_FAPI_RC_MEMORY);
404
405 r = Esys_TRSess_GetNonceTPM(esys_ctx, current_policy->session,
406 &current_policy->nonceTPM);
407 return_if_error(r, "Get TPM nonce.");
408
409 /* Concatenate objects needed for the authorization hash */
410 memcpy(&current_policy->buffer[offset], &current_policy->nonceTPM->buffer[0],
411 current_policy->nonceTPM->size);
412 offset += current_policy->nonceTPM->size;
413 memset(&current_policy->buffer[offset], 0, sizeof(INT32));
414 offset += sizeof(INT32);
415 memcpy(&current_policy->buffer[offset], &policy->cpHashA.buffer[0],
416 policy->cpHashA.size);
417 offset += policy->cpHashA.size;
418 memcpy(&current_policy->buffer[offset], &policy->policyRef.buffer[0],
419 policy->policyRef.size);
420 offset += policy->policyRef.size;
421 current_policy->buffer_size = offset;
422 fallthrough;
423
424 statecase(current_policy->state, POLICY_EXECUTE_CALLBACK);
425 ifapi_policyeval_EXEC_CB *cb = &current_policy->callbacks;
426 int pem_key_size;
427 TPM2B_PUBLIC tpm_public;
428
429 /* Recreate pem key from tpm public key */
430 if (!current_policy->pem_key) {
431 tpm_public.publicArea = policy->keyPublic;
432 tpm_public.size = 0;
433 r = ifapi_pub_pem_key_from_tpm(&tpm_public, &current_policy->pem_key,
434 &pem_key_size);
435 return_if_error(r, "Convert TPM public key into PEM key.");
436 }
437
438 /* Callback for signing the autorization hash. */
439 r = cb->cbsign(current_policy->pem_key, policy->publicKeyHint,
440 policy->keyPEMhashAlg, current_policy->buffer,
441 current_policy->buffer_size,
442 &signature_ossl, &signature_size,
443 cb->cbsign_userdata);
444 SAFE_FREE(current_policy->pem_key);
445 SAFE_FREE(current_policy->buffer);
446 try_again_or_error_goto(r, "Execute policy signature callback.", cleanup);
447
448 /* Convert signature into TPM format */
449 r = ifapi_der_sig_to_tpm(&policy->keyPublic, signature_ossl,
450 signature_size, policy->keyPEMhashAlg,
451 &policy->signature_tpm);
452 goto_if_error2(r, "Convert der signature into TPM format", cleanup);
453
454 SAFE_FREE(signature_ossl);
455
456 TPM2B_PUBLIC inPublic;
457 inPublic.size = 0;
458 inPublic.publicArea = policy->keyPublic;
459
460 /* Prepare the loading of the external public key, user for verificaton. */
461 r = Esys_LoadExternal_Async(esys_ctx,
462 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
463 NULL, &inPublic, TPM2_RH_OWNER);
464 goto_if_error(r, "LoadExternal_Async", cleanup);
465 fallthrough;
466
467 statecase(current_policy->state, POLICY_LOAD_KEY);
468 r = Esys_LoadExternal_Finish(esys_ctx, &current_policy->object_handle);
469 try_again_or_error(r, "Load external key.");
470
471 /* Prepare the policy execution. */
472 r = Esys_PolicySigned_Async(esys_ctx,
473 current_policy->object_handle,
474 current_policy->session,
475 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
476 current_policy->nonceTPM,
477 &policy->cpHashA,
478 &policy->policyRef, 0, &policy->signature_tpm);
479 SAFE_FREE(current_policy->nonceTPM);
480 goto_if_error(r, "Execute PolicySigned.", cleanup);
481 fallthrough;
482
483 statecase(current_policy->state, POLICY_EXECUTE_FINISH);
484 /* Finalize the policy execution if possible. */
485 r = Esys_PolicySigned_Finish(esys_ctx, NULL, NULL);
486 try_again_or_error(r, "Execute PolicySigned_Finish.");
487
488 r = Esys_FlushContext_Async(esys_ctx, current_policy->object_handle);
489 goto_if_error(r, "FlushContext_Async", cleanup);
490 fallthrough;
491
492 statecase(current_policy->state, POLICY_FLUSH_KEY);
493 r = Esys_FlushContext_Finish(esys_ctx);
494 try_again_or_error(r, "Flush key finish.");
495
496 current_policy->object_handle = ESYS_TR_NONE;
497 current_policy->state = POLICY_EXECUTE_INIT;
498 return r;
499
500 statecasedefault(current_policy->state);
501 }
502 cleanup:
503 SAFE_FREE(current_policy->pem_key);
504 SAFE_FREE(signature_ossl);
505 SAFE_FREE(current_policy->buffer);
506 SAFE_FREE(current_policy->pem_key);
507 /* In error cases object might not have been flushed. */
508 if (current_policy->object_handle != ESYS_TR_NONE)
509 Esys_FlushContext(esys_ctx, current_policy->object_handle);
510 return r;
511 }
512
513 /** Execute a policy that was signed by a certain key.
514 *
515 * All policies authorized by the key stored in the policy will be
516 * retrieved and one policy will be selected via a branch selection callback
517 * (see Fapi_SetBranchCB()) if more then one policy was found.
518 * The selected policy will be executed via a callback. For an example callback
519 * implementation see ifapi_exec_auth_policy().
520 *
521 * For an example callback implementation to executie of an authorized policy
522 * ifapi_exec_auth_policy()
523 *
524 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
525 * policy command.
526 * @param[in,out] policy The policy which defines the signing key and several
527 * additional parameters (nonce, policyRef ...). The policy
528 * digest will be added to the policy.
529 * @param[in] current_hash_alg The hash algorithm wich will be used for
530 * policy computation.
531 * @param[in,out] current_policy The policy context which stores the state
532 * of the policy execution.
533 * @retval TSS2_RC_SUCCESS on success.
534 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
535 * the function.
536 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
537 * this function needs to be called again.
538 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
539 * operation already pending.
540 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occured.
541 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
542 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
543 * was not successful.
544 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
545 * is not set.
546 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
547 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
548 */
549 static TSS2_RC
550 execute_policy_authorize(
551 ESYS_CONTEXT *esys_ctx,
552 TPMS_POLICYAUTHORIZE *policy,
553 TPMI_ALG_HASH hash_alg,
554 IFAPI_POLICY_EXEC_CTX *current_policy)
555 {
556 TSS2_RC r = TSS2_RC_SUCCESS;
557 TPM2B_PUBLIC public2b;
558 TPM2B_DIGEST aHash;
559 IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext;
560 size_t hash_size;
561 size_t size;
562 TPMT_TK_VERIFIED *ticket;
563 TPM2B_NAME *tmp_name = NULL;
564
565 LOG_TRACE("call");
566 public2b.size = 0;
567 if (!(hash_size = ifapi_hash_get_digest_size(hash_alg))) {
568 goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
569 "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
570 hash_alg);
571 }
572 switch (current_policy->state) {
573 statecase(current_policy->state, POLICY_EXECUTE_INIT);
574 current_policy->object_handle = ESYS_TR_NONE;
575 /* Execute authorized policy. */
576 ifapi_policyeval_EXEC_CB *cb = &current_policy->callbacks;
577 r = cb->cbauthpol(&policy->keyPublic, hash_alg, &policy->approvedPolicy,
578 &policy->signature, cb->cbauthpol_userdata);
579 return_try_again(r);
580 goto_if_error(r, "Execute authorized policy.", cleanup);
581
582 public2b.size = 0;
583 public2b.publicArea = policy->keyPublic;
584 r = Esys_LoadExternal_Async(esys_ctx,
585 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
586 NULL, &public2b, TPM2_RH_OWNER);
587 goto_if_error(r, "LoadExternal_Async", cleanup);
588 fallthrough;
589
590 statecase(current_policy->state, POLICY_LOAD_KEY);
591 r = Esys_LoadExternal_Finish(esys_ctx, &current_policy->object_handle);
592 try_again_or_error(r, "Load external key.");
593
594 /* Save key name for policy execution */
595 r = Esys_TR_GetName(esys_ctx, current_policy->object_handle, &tmp_name);
596 return_if_error(r, "Get key name.");
597 policy->keyName = *tmp_name;
598 SAFE_FREE(tmp_name);
599
600 /* Use policyRef and policy to compute authorization hash */
601 r = ifapi_crypto_hash_start(&cryptoContext, hash_alg);
602 return_if_error(r, "crypto hash start");
603
604 HASH_UPDATE_BUFFER(cryptoContext, &policy->approvedPolicy.buffer[0],
605 hash_size, r, cleanup);
606 HASH_UPDATE_BUFFER(cryptoContext, &policy->policyRef.buffer[0],
607 policy->policyRef.size, r, cleanup);
608 r = ifapi_crypto_hash_finish(&cryptoContext,
609 (uint8_t *) &aHash.buffer[0],
610 &size);
611 return_if_error(r, "crypto hash finish");
612
613 aHash.size = size;
614 LOGBLOB_TRACE(&policy->policyRef.buffer[0], policy->policyRef.size, "policyRef");
615 LOGBLOB_TRACE(&aHash.buffer[0], aHash.size, "aHash");
616
617 /* Verify the signature retrieved from the authorized policy against
618 the computed ahash. */
619 r = Esys_VerifySignature_Async(esys_ctx, current_policy->object_handle,
620 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
621 &aHash,
622 &policy->signature);
623 goto_if_error(r, "Verify signature", cleanup);
624 fallthrough;
625
626 statecase(current_policy->state, POLICY_VERIFY);
627 r = Esys_VerifySignature_Finish(esys_ctx, &ticket);
628 try_again_or_error(r, "Load external key.");
629
630 /* Execute policy authorize */
631 policy->checkTicket = *ticket;
632 SAFE_FREE(ticket);
633 r = Esys_PolicyAuthorize_Async(esys_ctx,
634 current_policy->session,
635 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
636 &policy->approvedPolicy,
637 &policy->policyRef,
638 &policy->keyName,
639 &policy->checkTicket);
640 goto_if_error(r, "Policy Authorize", cleanup);
641 fallthrough;
642
643 statecase(current_policy->state, POLICY_EXECUTE_FINISH);
644 r = Esys_PolicyAuthorize_Finish(esys_ctx);
645 try_again_or_error(r, "Load external key.");
646
647 r = Esys_FlushContext_Async(esys_ctx, current_policy->object_handle);
648 goto_if_error(r, "FlushContext_Async", cleanup);
649 fallthrough;
650
651 statecase(current_policy->state, POLICY_FLUSH_KEY);
652 /* Flush key used for verification. */
653 r = Esys_FlushContext_Finish(esys_ctx);
654 try_again_or_error(r, "Flush key finish.");
655
656 current_policy->object_handle = ESYS_TR_NONE;
657 current_policy->state = POLICY_EXECUTE_INIT;
658 break;
659
660 statecasedefault(current_policy->state);
661 }
662 cleanup:
663 /* In error cases object might not have been flushed. */
664 if (current_policy->object_handle != ESYS_TR_NONE)
665 Esys_FlushContext(esys_ctx, current_policy->object_handle);
666
667 return r;
668 }
669
670 /** Execute a policy whose digest is stored in the NV ram.
671 *
672 * The policy will be retrieved from policy store based on the policy digest
673 * stored in NV ram.
674 * The authorization for the NV object, the policy retrieval, and the execution
675 * is done via a callback. For an example callback implementation see
676 * ifapi_exec_auth_nv_policy().
677 *
678 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
679 * policy command.
680 * @param[in,out] policy The policy which defines the policy to be authorized
681 * and the used NV object.
682 * The policy digest will be added to the policy.
683 * @param[in] current_hash_alg The hash algorithm wich will be used for
684 * policy computation.
685 * @param[in,out] current_policy The policy context which stores the state
686 * of the policy execution.
687 * @retval TSS2_RC_SUCCESS on success.
688 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
689 * this function needs to be called again.
690 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
691 * operation already pending.
692 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
693 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
694 * the function.
695 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
696 * was not successful.
697 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
698 */
699 static TSS2_RC
700 execute_policy_authorize_nv(
701 ESYS_CONTEXT *esys_ctx,
702 TPMS_POLICYAUTHORIZENV *policy,
703 TPMI_ALG_HASH hash_alg,
704 IFAPI_POLICY_EXEC_CTX *current_policy)
705 {
706 TSS2_RC r = TSS2_RC_SUCCESS;
707 ifapi_policyeval_EXEC_CB *cb;
708
709 LOG_DEBUG("call");
710 cb = &current_policy->callbacks;
711
712 switch (current_policy->state) {
713 statecase(current_policy->state, POLICY_EXECUTE_INIT)
714 /* Execute the policy stored in the NV object. */
715 r = cb->cbauthnv(&policy->nvPublic, hash_alg, cb->cbauthpol_userdata);
716 try_again_or_error(r, "Execute policy authorize nv callback.");
717
718 r = ifapi_nv_get_name(&policy->nvPublic, &current_policy->name);
719 return_if_error(r, "Compute NV name");
720 fallthrough;
721
722 statecase(current_policy->state, POLICY_AUTH_CALLBACK)
723 /* Authorize the NV object for policy execution. */
724 r = cb->cbauth(&current_policy->name,
725 &current_policy->object_handle,
726 &current_policy->auth_handle,
727 &current_policy->auth_session, cb->cbauth_userdata);
728 return_try_again(r);
729 goto_if_error(r, "Execute authorized policy.", cleanup);
730 fallthrough;
731
732 statecase(current_policy->state, POLICY_EXEC_ESYS)
733 LOG_DEBUG("**STATE** POLICY_EXEC_ESYS");
734 /* Prepare the policy execution. */
735 r = Esys_PolicyAuthorizeNV_Async(esys_ctx,
736 current_policy->auth_handle,
737 current_policy->object_handle,
738 current_policy->session,
739 current_policy->auth_session, ESYS_TR_NONE,
740 ESYS_TR_NONE);
741 goto_if_error(r, "PolicyAuthorizeNV_Async", cleanup);
742 fallthrough;
743
744 statecase(current_policy->state, POLICY_AUTH_SENT)
745 /* Finalize the policy execution if possible. */
746 r = Esys_PolicyAuthorizeNV_Finish(esys_ctx);
747 return_try_again(r);
748 goto_if_error(r, "FAPI PolicyAuthorizeNV_Finish", cleanup);
749 break;
750
751 statecasedefault(current_policy->state);
752 }
753 cleanup:
754 return r;
755 }
756
757 /** Execute a policy based on a secret-based authorization.
758 *
759 * The policy defines an object whose secret is needed for policy execution.
760 * The authorization of the object is done via a callback.
761 * For an example callback implementation see ifapi_policyeval_cbauth;().
762 *
763 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
764 * policy command.
765 * @param[in,out] policy The policy which defines the object whose secret
766 * is needed for policy execution.
767 * The policy digest will be added to the policy.
768 * @param[in] current_hash_alg The hash algorithm wich will be used for
769 * policy computation.
770 * @param[in,out] current_policy The policy context which stores the state
771 * of the policy execution.
772 * @retval TSS2_RC_SUCCESS on success.
773 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
774 * this function needs to be called again.
775 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
776 * operation already pending.
777 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
778 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
779 */
780 static TSS2_RC
781 execute_policy_secret(
782 ESYS_CONTEXT *esys_ctx,
783 TPMS_POLICYSECRET *policy,
784 TPMI_ALG_HASH hash_alg,
785 IFAPI_POLICY_EXEC_CTX *current_policy)
786 {
787 TSS2_RC r = TSS2_RC_SUCCESS;
788 (void)hash_alg;
789
790 LOG_DEBUG("call");
791
792 switch (current_policy->state) {
793 statecase(current_policy->state, POLICY_EXECUTE_INIT)
794 ifapi_policyeval_EXEC_CB *cb = &current_policy->callbacks;
795 /* Callback for the object authorization. */
796 r = cb->cbauth(&policy->objectName,
797 &current_policy->object_handle,
798 &current_policy->auth_handle,
799 &current_policy->auth_session, cb->cbauth_userdata);
800 return_try_again(r);
801 goto_if_error(r, "Authorize object callback.", cleanup);
802 fallthrough;
803
804 statecase(current_policy->state, POLICY_EXEC_ESYS)
805 r = Esys_TRSess_GetNonceTPM(esys_ctx, current_policy->session,
806 &current_policy->nonceTPM);
807 goto_if_error(r, "Get TPM nonce.", cleanup);
808
809 policy->nonceTPM = *(current_policy->nonceTPM);
810 SAFE_FREE(current_policy->nonceTPM);
811
812 /* Prepare the policy execution. */
813 r = Esys_PolicySecret_Async(esys_ctx,
814 current_policy->auth_handle,
815 current_policy->session,
816 current_policy->auth_session, ESYS_TR_NONE,
817 ESYS_TR_NONE, &policy->nonceTPM,
818 &policy->cpHashA, &policy->policyRef,
819 0);
820 goto_if_error(r, "PolicySecret_Async", cleanup);
821 fallthrough;
822
823 statecase(current_policy->state, POLICY_AUTH_SENT)
824 /* Finalize the policy execution if possible. */
825 r = Esys_PolicySecret_Finish(esys_ctx, NULL,
826 NULL);
827 return_try_again(r);
828 goto_if_error(r, "FAPI PolicyAuthorizeNV_Finish", cleanup);
829 break;
830
831 statecasedefault(current_policy->state);
832 }
833
834 cleanup:
835 return r;
836 }
837
838 /** Execute a policy depending on the TPM timers.
839 *
840 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
841 * policy command.
842 * @param[in,out] policy The policy which defines the values for the comparision
843 * with the TPM timers and the comparision operation.
844 * The policy digest will be added to the policy.
845 * @param[in] current_hash_alg The hash algorithm wich will be used for
846 * policy computation.
847 * @param[in,out] current_policy The policy context which stores the state
848 * of the policy execution.
849 * @retval TSS2_RC_SUCCESS on success.
850 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
851 * this function needs to be called again.
852 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
853 * operation already pending.
854 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
855 */
856 static TSS2_RC
857 execute_policy_counter_timer(
858 ESYS_CONTEXT *esys_ctx,
859 TPMS_POLICYCOUNTERTIMER *policy,
860 IFAPI_POLICY_EXEC_CTX *current_policy)
861 {
862 TSS2_RC r = TSS2_RC_SUCCESS;
863
864 LOG_TRACE("call");
865
866 switch (current_policy->state) {
867 statecase(current_policy->state, POLICY_EXECUTE_INIT)
868 /* Prepare the policy execution. */
869 r = Esys_PolicyCounterTimer_Async(esys_ctx,
870 current_policy->session,
871 ESYS_TR_NONE, ESYS_TR_NONE,
872 ESYS_TR_NONE,
873 &policy->operandB,
874 policy->offset,
875 policy->operation);
876 return_if_error(r, "Execute PolicyCounter.");
877 fallthrough;
878
879 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
880 /* Finalize the policy execution if possible. */
881 r = Esys_PolicyCounterTimer_Finish(esys_ctx);
882 try_again_or_error(r, "Execute PolicyCounterTImer_Finish.");
883
884 current_policy->state = POLICY_EXECUTE_INIT;
885 return r;
886
887 statecasedefault(current_policy->state);
888 }
889 return r;
890 }
891
892 /** Execute a policy depending on physical presence.
893 *
894 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
895 * policy command.
896 * @param[in,out] policy The policy indicating that physical presence is needed.
897 * @param[in,out] current_policy The policy context which stores the state
898 * of the policy execution.
899 * @retval TSS2_RC_SUCCESS on success.
900 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
901 * this function needs to be called again.
902 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
903 * operation already pending.
904 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
905 */
906 static TSS2_RC
907 execute_policy_physical_presence(
908 ESYS_CONTEXT *esys_ctx,
909 TPMS_POLICYPHYSICALPRESENCE *policy,
910 IFAPI_POLICY_EXEC_CTX *current_policy)
911 {
912 TSS2_RC r = TSS2_RC_SUCCESS;
913 (void)policy;
914
915 LOG_TRACE("call");
916
917 switch (current_policy->state) {
918 statecase(current_policy->state, POLICY_EXECUTE_INIT)
919 /* Prepare the policy execution. */
920 r = Esys_PolicyPhysicalPresence_Async(esys_ctx,
921 current_policy->session,
922 ESYS_TR_NONE, ESYS_TR_NONE,
923 ESYS_TR_NONE);
924 return_if_error(r, "Execute PolicyPhysicalpresence.");
925 fallthrough;
926
927 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
928 /* Finalize the policy execution if possible. */
929 r = Esys_PolicyPhysicalPresence_Finish(esys_ctx);
930 try_again_or_error(r, "Execute PolicyPhysicalPresence_Finish.");
931
932 current_policy->state = POLICY_EXECUTE_INIT;
933 return r;
934
935 statecasedefault(current_policy->state);
936 }
937 return r;
938 }
939
940 /** Execute a policy for binding a authorization value of the authorized entity.
941 *
942 * The authValue will be included in hmacKey of the session.
943
944 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
945 * policy command.
946 * @param[in,out] policy The policy indicating that a auth value is needed.
947 * @param[in,out] current_policy The policy context which stores the state
948 * of the policy execution.
949 * @retval TSS2_RC_SUCCESS on success.
950 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
951 * this function needs to be called again.
952 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
953 * operation already pending.
954 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
955 */
956 static TSS2_RC
957 execute_policy_auth_value(
958 ESYS_CONTEXT *esys_ctx,
959 TPMS_POLICYAUTHVALUE *policy,
960 IFAPI_POLICY_EXEC_CTX *current_policy)
961 {
962 TSS2_RC r = TSS2_RC_SUCCESS;
963 (void)policy;
964
965 LOG_TRACE("call");
966
967 switch (current_policy->state) {
968 statecase(current_policy->state, POLICY_EXECUTE_INIT)
969 /* Prepare the policy execution. */
970 r = Esys_PolicyAuthValue_Async(esys_ctx,
971 current_policy->session,
972 ESYS_TR_NONE, ESYS_TR_NONE,
973 ESYS_TR_NONE);
974 return_if_error(r, "Execute PolicyAuthValue.");
975 fallthrough;
976
977 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
978 /* Finalize the policy execution if possible. */
979 r = Esys_PolicyAuthValue_Finish(esys_ctx);
980 try_again_or_error(r, "Execute PolicyAuthValue_Finish.");
981
982 current_policy->state = POLICY_EXECUTE_INIT;
983 return r;
984
985 statecasedefault(current_policy->state);
986 }
987 return r;
988 }
989
990 /** Execute a policy for binding a authorization value of the authorized object.
991 *
992 * The authValue of the authorized object will be checked when the session is used
993 * for authorization..
994 *
995 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
996 * policy command.
997 * @param[in,out] policy The policy indicating that a auth value is needed.
998 * @param[in,out] current_policy The policy context which stores the state
999 * of the policy execution.
1000 * @retval TSS2_RC_SUCCESS on success.
1001 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1002 * this function needs to be called again.
1003 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1004 * operation already pending.
1005 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1006 */
1007 static TSS2_RC
1008 execute_policy_password(
1009 ESYS_CONTEXT *esys_ctx,
1010 TPMS_POLICYPASSWORD *policy,
1011 IFAPI_POLICY_EXEC_CTX *current_policy)
1012 {
1013 TSS2_RC r = TSS2_RC_SUCCESS;
1014 (void)policy;
1015
1016 LOG_TRACE("call");
1017
1018 switch (current_policy->state) {
1019 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1020 /* Prepare the policy execution. */
1021 r = Esys_PolicyPassword_Async(esys_ctx,
1022 current_policy->session,
1023 ESYS_TR_NONE, ESYS_TR_NONE,
1024 ESYS_TR_NONE);
1025 return_if_error(r, "Execute PolicyPassword.");
1026 fallthrough;
1027
1028 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1029 /* Finalize the policy execution if possible. */
1030 r = Esys_PolicyPassword_Finish(esys_ctx);
1031 try_again_or_error(r, "Execute PolicyPassword_Finish.");
1032
1033 current_policy->state = POLICY_EXECUTE_INIT;
1034 return r;
1035
1036 statecasedefault(current_policy->state);
1037 }
1038 return r;
1039 }
1040
1041 /** Execute a policy to limit an authorization to a specific command code.
1042 *
1043 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1044 * policy command.
1045 * @param[in,out] policy The policy with the command code used fo limitting.
1046 * @param[in,out] current_policy The policy context which stores the state
1047 * of the policy execution.
1048 * @retval TSS2_RC_SUCCESS on success.
1049 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1050 * this function needs to be called again.
1051 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1052 * operation already pending.
1053 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1054 */
1055 static TSS2_RC
1056 execute_policy_command_code(
1057 ESYS_CONTEXT *esys_ctx,
1058 TPMS_POLICYCOMMANDCODE *policy,
1059 IFAPI_POLICY_EXEC_CTX *current_policy)
1060 {
1061 TSS2_RC r = TSS2_RC_SUCCESS;
1062
1063 LOG_TRACE("call");
1064
1065 switch (current_policy->state) {
1066 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1067 /* Prepare the policy execution. */
1068 r = Esys_PolicyCommandCode_Async(esys_ctx,
1069 current_policy->session,
1070 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1071 policy->code);
1072 return_if_error(r, "Execute PolicyCommandCode.");
1073 fallthrough;
1074
1075 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1076 /* Finalize the policy execution if possible. */
1077 r = Esys_PolicyCommandCode_Finish(esys_ctx);
1078 try_again_or_error(r, "Execute PolicyCommandCode_Finish.");
1079
1080 current_policy->state = POLICY_EXECUTE_INIT;
1081 return r;
1082
1083 statecasedefault(current_policy->state)
1084 }
1085 return r;
1086 }
1087
1088 /** Execute a policy for binding the policy to a specific set of TPM entities.
1089 *
1090 * Up to three entity names can be defined in the policy.
1091 *
1092 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1093 * policy command.
1094 * @param[in,out] policy The policy with the entity names.
1095 * @param[in,out] current_policy The policy context which stores the state
1096 * of the policy execution.
1097 * @retval TSS2_RC_SUCCESS on success.
1098 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1099 * this function needs to be called again.
1100 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1101 * operation already pending.
1102 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1103 */
1104 static TSS2_RC
1105 execute_policy_name_hash(
1106 ESYS_CONTEXT *esys_ctx,
1107 TPMS_POLICYNAMEHASH *policy,
1108 IFAPI_POLICY_EXEC_CTX *current_policy)
1109 {
1110 TSS2_RC r = TSS2_RC_SUCCESS;
1111
1112 LOG_TRACE("call");
1113
1114 switch (current_policy->state) {
1115 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1116 /* Prepare the policy execution. */
1117 r = Esys_PolicyNameHash_Async(esys_ctx,
1118 current_policy->session,
1119 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1120 &policy->nameHash);
1121 return_if_error(r, "Execute PolicyNameH.");
1122 fallthrough;
1123
1124 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1125 /* Finalize the policy execution if possible. */
1126 r = Esys_PolicyNameHash_Finish(esys_ctx);
1127 try_again_or_error(r, "Execute PolicyNameHash_Finish.");
1128
1129 current_policy->state = POLICY_EXECUTE_INIT;
1130 return r;
1131
1132 statecasedefault(current_policy->state)
1133 }
1134 return r;
1135 }
1136
1137 /** Execute a policy for binding the policy to command parameters.
1138 *
1139 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1140 * policy command.
1141 * @param[in,out] policy The policy with the cp hash.
1142 * @param[in,out] current_policy The policy context which stores the state
1143 * of the policy execution.
1144 * @retval TSS2_RC_SUCCESS on success.
1145 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1146 * this function needs to be called again.
1147 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1148 * operation already pending.
1149 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1150 */
1151 static TSS2_RC
1152 execute_policy_cp_hash(
1153 ESYS_CONTEXT *esys_ctx,
1154 TPMS_POLICYCPHASH *policy,
1155 IFAPI_POLICY_EXEC_CTX *current_policy)
1156 {
1157 TSS2_RC r = TSS2_RC_SUCCESS;
1158
1159 LOG_TRACE("call");
1160
1161 switch (current_policy->state) {
1162 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1163 /* Prepare the policy execution. */
1164 r = Esys_PolicyCpHash_Async(esys_ctx,
1165 current_policy->session,
1166 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1167 &policy->cpHash);
1168 return_if_error(r, "Execute PolicyNameH.");
1169
1170 fallthrough;
1171
1172 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1173 /* Finalize the policy execution if possible. */
1174 r = Esys_PolicyCpHash_Finish(esys_ctx);
1175 try_again_or_error(r, "Execute PolicyCpHash_Finish.");
1176
1177 current_policy->state = POLICY_EXECUTE_INIT;
1178 return r;
1179
1180 statecasedefault(current_policy->state);
1181 }
1182 return r;
1183 }
1184
1185 /** Execute a policy for binding the policy to a certain locality.
1186 *
1187 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1188 * policy command.
1189 * @param[in,out] policy The policy with the locality.
1190 * @param[in,out] current_policy The policy context which stores the state
1191 * of the policy execution.
1192 * @retval TSS2_RC_SUCCESS on success.
1193 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1194 * this function needs to be called again.
1195 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1196 * operation already pending.
1197 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1198 */
1199 static TSS2_RC
1200 execute_policy_locality(
1201 ESYS_CONTEXT *esys_ctx,
1202 TPMS_POLICYLOCALITY *policy,
1203 IFAPI_POLICY_EXEC_CTX *current_policy)
1204 {
1205 TSS2_RC r = TSS2_RC_SUCCESS;
1206
1207 LOG_TRACE("call");
1208
1209 switch (current_policy->state) {
1210 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1211 /* Prepare the policy execution. */
1212 r = Esys_PolicyLocality_Async(esys_ctx,
1213 current_policy->session,
1214 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1215 policy->locality);
1216 return_if_error(r, "Execute PolicyLocality.");
1217 fallthrough;
1218
1219 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1220 /* Finalize the policy execution if possible. */
1221 r = Esys_PolicyLocality_Finish(esys_ctx);
1222 try_again_or_error(r, "Execute PolicyNV_Finish.");
1223
1224 current_policy->state = POLICY_EXECUTE_INIT;
1225 return r;
1226
1227 statecasedefault(current_policy->state);
1228 }
1229 return r;
1230 }
1231
1232 /** Execute a policy for binding the policy to the NV written state.
1233 *
1234 * The state NV written yes or NV written no can be defined in the policy.
1235 *
1236 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1237 * policy command.
1238 * @param[in,out] policy The policy with the NV written switch YES or NO.
1239 * @param[in,out] current_policy The policy context which stores the state
1240 * of the policy execution.
1241 * @retval TSS2_RC_SUCCESS on success.
1242 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1243 * this function needs to be called again.
1244 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1245 * operation already pending.
1246 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1247 */
1248 static TSS2_RC
1249 execute_policy_nv_written(
1250 ESYS_CONTEXT *esys_ctx,
1251 TPMS_POLICYNVWRITTEN *policy,
1252 IFAPI_POLICY_EXEC_CTX *current_policy)
1253 {
1254 TSS2_RC r = TSS2_RC_SUCCESS;
1255
1256 LOG_TRACE("call");
1257
1258 switch (current_policy->state) {
1259 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1260 /* Prepare the policy execution. */
1261 r = Esys_PolicyNvWritten_Async(esys_ctx,
1262 current_policy->session,
1263 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1264 policy->writtenSet);
1265 return_if_error(r, "Execute PolicyNvWritten.");
1266 fallthrough;
1267
1268 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1269 /* Finalize the policy execution if possible. */
1270 r = Esys_PolicyNvWritten_Finish(esys_ctx);
1271 try_again_or_error(r, "Execute PolicyNV_Finish.");
1272
1273 current_policy->state = POLICY_EXECUTE_INIT;
1274 return r;
1275
1276 statecasedefault(current_policy->state);
1277 }
1278 return r;
1279 }
1280
1281 /** Execute a policy for binding the policy to the NV written state.
1282 *
1283 * The state NV written yes or NV written no can be defined in the policy.
1284 *
1285 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1286 * policy command.
1287 * @param[in,out] policy The policy with the NV written switch YES or NO.
1288 * @param[in,out] current_policy The policy context which stores the state
1289 * of the policy execution.
1290 * @retval TSS2_RC_SUCCESS on success.
1291 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1292 * this function needs to be called again.
1293 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1294 * operation already pending.
1295 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1296 */
1297 static TSS2_RC
1298 execute_policy_or(
1299 ESYS_CONTEXT *esys_ctx,
1300 TPMS_POLICYOR *policy,
1301 TPMI_ALG_HASH current_hash_alg,
1302 IFAPI_POLICY_EXEC_CTX *current_policy)
1303 {
1304 TSS2_RC r = TSS2_RC_SUCCESS;
1305
1306 LOG_TRACE("call");
1307
1308 switch (current_policy->state) {
1309 statecase(current_policy->state, POLICY_EXECUTE_INIT)
1310 /* Prepare the policy execution. */
1311 r = compute_or_digest_list(policy->branches, current_hash_alg,
1312 &current_policy->digest_list);
1313 return_if_error(r, "Compute policy or digest list.");
1314
1315 r = Esys_PolicyOR_Async(esys_ctx,
1316 current_policy->session,
1317 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
1318 &current_policy->digest_list);
1319 return_if_error(r, "Execute PolicyPCR.");
1320 fallthrough;
1321 statecase(current_policy->state, POLICY_EXECUTE_FINISH)
1322 /* Finalize the policy execution if possible. */
1323 r = Esys_PolicyOR_Finish(esys_ctx);
1324 try_again_or_error(r, "Execute PolicyPCR_Finish.");
1325
1326 return r;
1327
1328 statecasedefault(current_policy->state);
1329 }
1330 }
1331
1332 /** Execute a policy for executing a callback during policy execution.
1333 *
1334 * The action name stored in the policy name will be passed do the callback
1335 * function. The policy action callback has to be set with the function:
1336 * Fapi_SetPolicyActionCB().
1337 *
1338 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1339 * policy command.
1340 * @param[in,out] policy The policy with action name.
1341 * @param[in,out] current_policy The policy context which stores the state
1342 * of the policy execution.
1343 * @retval TSS2_RC_SUCCESS on success.
1344 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1345 * this function needs to be called again.
1346 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1347 * operation already pending.
1348 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1349 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1350 * is not set.
1351 */
1352 static TSS2_RC
1353 execute_policy_action(
1354 ESYS_CONTEXT *esys_ctx,
1355 TPMS_POLICYACTION *policy,
1356 IFAPI_POLICY_EXEC_CTX *current_policy)
1357 {
1358 TSS2_RC r = TSS2_RC_SUCCESS;
1359 (void)(esys_ctx);
1360 LOG_TRACE("call");
1361
1362 switch (current_policy->state) {
1363 statecase(current_policy->state, POLICY_EXECUTE_INIT);
1364 ifapi_policyeval_EXEC_CB *cb = &current_policy->callbacks;
1365
1366 /* Execute the callback and try it again if the callback is not finished. */
1367 r = cb->cbaction(policy->action, cb->cbaction_userdata);
1368 try_again_or_error(r, "Execute policy action callback.");
1369 return r;
1370
1371 statecasedefault(current_policy->state);
1372 }
1373 }
1374
1375 /** Execute a policy element depending on the type.
1376 *
1377 * @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
1378 * policy command.
1379 * @param[in,out] policy The policy element with the policy to be executed and
1380 * the type of the policy.
1381 * @param[in,out] current_policy The policy context which stores the state
1382 * of the policy execution.
1383 * @retval TSS2_RC_SUCCESS on success.
1384 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occured.
1385 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1386 * this function needs to be called again.
1387 */
1388 static TSS2_RC
1389 execute_policy_element(
1390 ESYS_CONTEXT *esys_ctx,
1391 TPMT_POLICYELEMENT *policy,
1392 TPMI_ALG_HASH hash_alg,
1393 IFAPI_POLICY_EXEC_CTX *current_policy)
1394 {
1395 TSS2_RC r = TSS2_RC_SUCCESS;
1396
1397 LOG_TRACE("call");
1398
1399 switch (policy->type) {
1400 case POLICYSECRET:
1401 r = execute_policy_secret(esys_ctx,
1402 &policy->element.PolicySecret,
1403 hash_alg,
1404 current_policy);
1405 try_again_or_error_goto(r, "Execute policy authorize", error);
1406 break;
1407 case POLICYPCR:
1408 r = execute_policy_pcr(esys_ctx,
1409 &policy->element.PolicyPCR,
1410 hash_alg, current_policy);
1411 try_again_or_error_goto(r, "Execute policy pcr", error);
1412 break;
1413 case POLICYAUTHVALUE:
1414 r = execute_policy_auth_value(esys_ctx,
1415 &policy->element.PolicyAuthValue,
1416 current_policy);
1417 try_again_or_error_goto(r, "Execute policy auth value", error);
1418 break;
1419 case POLICYOR:
1420 r = execute_policy_or(esys_ctx,
1421 &policy->element.PolicyOr,
1422 hash_alg, current_policy);
1423 try_again_or_error_goto(r, "Execute policy or", error);
1424 break;
1425 case POLICYSIGNED:
1426 r = execute_policy_signed(esys_ctx,
1427 &policy->element.PolicySigned,
1428 current_policy);
1429 try_again_or_error_goto(r, "Execute policy signed", error);
1430 break;
1431 case POLICYAUTHORIZE:
1432 r = execute_policy_authorize(esys_ctx,
1433 &policy->element.PolicyAuthorize,
1434 hash_alg,
1435 current_policy);
1436 try_again_or_error_goto(r, "Execute policy authorize", error);
1437 break;
1438 case POLICYAUTHORIZENV:
1439 r = execute_policy_authorize_nv(esys_ctx,
1440 &policy->element.PolicyAuthorizeNv,
1441 hash_alg,
1442 current_policy);
1443 try_again_or_error_goto(r, "Execute policy authorize", error);
1444 break;
1445 case POLICYNV:
1446 r = execute_policy_nv(esys_ctx,
1447 &policy->element.PolicyNV,
1448 current_policy);
1449 try_again_or_error_goto(r, "Execute policy nv", error);
1450 break;
1451 case POLICYDUPLICATIONSELECT:
1452 r = execute_policy_duplicate(esys_ctx,
1453 &policy->element.PolicyDuplicationSelect,
1454 current_policy);
1455 try_again_or_error_goto(r, "Execute policy duplicate", error);
1456 break;
1457 case POLICYNVWRITTEN:
1458 r = execute_policy_nv_written(esys_ctx,
1459 &policy->element.PolicyNvWritten,
1460 current_policy);
1461 try_again_or_error_goto(r, "Execute policy nv written", error);
1462 break;
1463 case POLICYLOCALITY:
1464 r = execute_policy_locality(esys_ctx,
1465 &policy->element.PolicyLocality,
1466 current_policy);
1467 try_again_or_error_goto(r, "Execute policy locality", error);
1468 break;
1469 case POLICYCOMMANDCODE:
1470 r = execute_policy_command_code(esys_ctx,
1471 &policy->element.PolicyCommandCode,
1472 current_policy);
1473 try_again_or_error_goto(r, "Execute policy command code", error);
1474 break;
1475 case POLICYNAMEHASH:
1476 r = execute_policy_name_hash(esys_ctx,
1477 &policy->element.PolicyNameHash,
1478 current_policy);
1479 try_again_or_error_goto(r, "Execute policy name hash", error);
1480 break;
1481 case POLICYCPHASH:
1482 r = execute_policy_cp_hash(esys_ctx,
1483 &policy->element.PolicyCpHash,
1484 current_policy);
1485 try_again_or_error_goto(r, "Execute policy cp hash", error);
1486 break;
1487 case POLICYPHYSICALPRESENCE:
1488 r = execute_policy_physical_presence(esys_ctx,
1489 &policy->element.PolicyPhysicalPresence,
1490 current_policy);
1491 try_again_or_error_goto(r, "Execute policy physical presence", error);
1492 break;
1493 case POLICYPASSWORD:
1494 r = execute_policy_password(esys_ctx,
1495 &policy->element.PolicyPassword,
1496 current_policy);
1497 try_again_or_error_goto(r, "Execute policy password", error);
1498 break;
1499 case POLICYCOUNTERTIMER:
1500 r = execute_policy_counter_timer(esys_ctx,
1501 &policy->element.PolicyCounterTimer,
1502 current_policy);
1503 try_again_or_error_goto(r, "Execute policy counter timer", error);
1504 break;
1505 case POLICYACTION:
1506 r = execute_policy_action(esys_ctx,
1507 &policy->element.PolicyAction,
1508 current_policy);
1509 try_again_or_error_goto(r, "Execute policy action", error);
1510 break;
1511
1512 default:
1513 return_error(TSS2_FAPI_RC_GENERAL_FAILURE,
1514 "Policy not implemented");
1515 }
1516 return r;
1517 error:
1518 return r;
1519
1520 /* All policies executed successfully */
1521 return r;
1522 }
1523
1524 /** Compute execution order for policies based on branch selection.
1525 *
1526 * To simplify asynncronous policy executiion a linked list of the policy structures
1527 * needed for execution based on the result of the branch selection callbacks
1528 * is computed.
1529 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1530 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1531 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1532 * is not set.
1533 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1534 */
1535 static TSS2_RC
1536 compute_policy_list(
1537 IFAPI_POLICY_EXEC_CTX *pol_ctx,
1538 TPML_POLICYELEMENTS *elements)
1539 {
1540 TSS2_RC r = TSS2_RC_SUCCESS;
1541 TPML_POLICYBRANCHES *branches;
1542 TPML_POLICYELEMENTS *or_elements;
1543 size_t branch_idx, i;
1544
1545 for (i = 0; i < elements->count; i++) {
1546 if (elements->elements[i].type == POLICYOR) {
1547 branches = elements->elements[i].element.PolicyOr.branches;
1548 r = pol_ctx->callbacks.cbpolsel(branches, &branch_idx,
1549 pol_ctx->callbacks.cbpolsel_userdata);
1550 return_if_error(r, "Select policy branch.");
1551 or_elements = branches->authorizations[branch_idx].policy;
1552 r = compute_policy_list(pol_ctx, or_elements);
1553 return_if_error(r, "Compute policy digest list for policy or.");
1554 }
1555 r = append_object_to_list(&elements->elements[i], &pol_ctx->policy_elements);
1556 return_if_error(r, "Extend policy list.");
1557 }
1558 return r;
1559 }
1560
1561 /** Initialize policy element list to be executed and store policy in context.
1562 *
1563 * @param[in] pol_ctx Context for execution of a list of policy elements.
1564 * @param[in] hash_alg The hash algorithm used for the policy computation.
1565 * @param[in,out] policy The policy to be executed. Some policy elements will
1566 * be used to store computed parameters needed for policy
1567 * execution.
1568 * @retval TSS2_RC_SUCCESS on success.
1569 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for branch selection is
1570 * not defined. This callback will be needed of or policies have to be
1571 * executed.
1572 * @retval TSS2_FAPI_RC_BAD_VALUE If the computed branch index deliverd by the
1573 * callback does not identify a branch.
1574 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1575 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1576 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1577 */
1578 TSS2_RC
1579 ifapi_policyeval_execute_prepare(
1580 IFAPI_POLICY_EXEC_CTX *pol_ctx,
1581 TPMI_ALG_HASH hash_alg,
1582 TPMS_POLICY *policy)
1583 {
1584 TSS2_RC r;
1585
1586 pol_ctx->policy = policy;
1587 pol_ctx->hash_alg = hash_alg;
1588 r = compute_policy_list(pol_ctx, policy->policy);
1589 return_if_error(r, "Compute list of policy elements to be executed.");
1590
1591 return TSS2_RC_SUCCESS;
1592 }
1593
1594 /** Execute all policy commands defined by a list of policy elements.
1595 *
1596 * @retval TSS2_RC_SUCCESS on success.
1597 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
1598 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
1599 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
1600 * store.
1601 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
1602 * not successful.
1603 * @retval TSS2_FAPI_RC_BAD_TEMPLATE In a invalid policy is loaded during execution.
1604 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1605 * this function needs to be called again.
1606 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1607 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1608 * operation already pending.
1609 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1610 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1611 * during authorization.
1612 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
1613 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
1614 * is not set.
1615 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
1616 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
1617 */
1618 TSS2_RC
1619 ifapi_policyeval_execute(
1620 ESYS_CONTEXT *esys_ctx,
1621 IFAPI_POLICY_EXEC_CTX *current_policy)
1622
1623 {
1624 TSS2_RC r = TSS2_RC_SUCCESS;
1625 NODE_OBJECT_T *current_policy_element;
1626
1627 LOG_DEBUG("call");
1628
1629 while (current_policy->policy_elements) {
1630 r = execute_policy_element(esys_ctx,
1631 (TPMT_POLICYELEMENT *)
1632 current_policy->policy_elements->object,
1633 current_policy->hash_alg,
1634 current_policy);
1635 return_try_again(r);
1636
1637 if (r != TSS2_RC_SUCCESS) {
1638 Esys_FlushContext(esys_ctx, current_policy->session);
1639 current_policy->session = ESYS_TR_NONE;
1640 ifapi_free_node_list(current_policy->policy_elements);
1641
1642 }
1643 return_if_error(r, "Execute policy.");
1644
1645 current_policy_element = current_policy->policy_elements;
1646 current_policy->policy_elements = current_policy->policy_elements->next;
1647 SAFE_FREE(current_policy_element);
1648 }
1649 return r;
1650
1651 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef FAPI_POLICY_EXECUTE_H
6 #define FAPI_POLICY_EXECUTE_H
7
8 #include <stdint.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <json-c/json.h>
13 #include <json-c/json_util.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17
18 TSS2_RC
19 ifapi_extend_authorization(
20 TPMS_POLICY *policy,
21 TPMS_POLICYAUTHORIZATION *authorization);
22
23 typedef TSS2_RC(*Policy_Compare_Object)(
24 TPMS_POLICY *policy,
25 void *object1,
26 void *object2,
27 bool *found);
28
29 /** List of policies which fulfill a certain predicate.
30 *
31 * The elements are stored in a linked list.
32 */
33 struct POLICY_LIST {
34 const char *path; /**< The path of the policy object */
35 TPMS_POLICY policy; /**< The policy object */
36 struct POLICY_LIST *next; /**< Pointer to next element */
37 };
38
39 /** List of policies which fulfill a certain predicate.
40 *
41 * The elements are stored in a linked list.
42 */
43 struct policy_object_node {
44 const char *path; /**< The path of the policy object */
45 TPMS_POLICY policy; /**< The policy object */
46 struct policy_object_node *next; /**< Pointer to next element */
47 };
48
49 typedef TSS2_RC (*ifapi_policyexec_cbauth) (
50 TPM2B_NAME *name,
51 ESYS_TR *object_handle,
52 ESYS_TR *auth_handle,
53 ESYS_TR *authSession,
54 void *userdata);
55
56 typedef TSS2_RC (*ifapi_policyexec_cbdup) (
57 TPM2B_NAME *name,
58 void *userdata);
59
60 typedef TSS2_RC (*ifapi_policyexec_cbpolsel) (
61 TPML_POLICYBRANCHES *branches,
62 size_t *branch_idx,
63 void *userdata);
64
65 typedef TSS2_RC (*ifapi_policyexec_cbsign) (
66 char *key_pem,
67 char *public_key_hint,
68 TPMI_ALG_HASH key_pem_hash_alg,
69 uint8_t *buffer,
70 size_t buffer_size,
71 uint8_t **signature,
72 size_t *signature_size,
73 void *userdata);
74
75 typedef TSS2_RC (*ifapi_policyexec_cbauthpol) (
76 TPMT_PUBLIC *key_public,
77 TPMI_ALG_HASH hash_alg,
78 TPM2B_DIGEST *digest,
79 TPMT_SIGNATURE *signature,
80 void *userdata);
81
82 typedef TSS2_RC (*ifapi_policyexec_cbauthnv) (
83 TPM2B_NV_PUBLIC *nv_public,
84 TPMI_ALG_HASH hash_alg,
85 void *userdata);
86
87 typedef TSS2_RC (*ifapi_policyexec_cbaction) (
88 const char *action,
89 void *userdata);
90
91 typedef struct {
92 ifapi_policyexec_cbauth cbauth; /**< Callback to authorize an object
93 retrieved by name in keystore */
94 void *cbauth_userdata;
95 ifapi_policyexec_cbpolsel cbpolsel; /**< Callback for selection of policy
96 branch */
97 void *cbpolsel_userdata;
98 ifapi_policyexec_cbsign cbsign; /**< Callback for policy sign */
99 void *cbsign_userdata;
100 ifapi_policyexec_cbauthpol cbauthpol; /**< Callback for policy authorize */
101 void *cbauthpol_userdata;
102 ifapi_policyexec_cbauthnv cbauthnv; /**< Callback for policy authorize nv */
103 void *cbauthnv_userdata;
104 ifapi_policyexec_cbdup cbdup; /**< Callback for policy duplication
105 select */
106 void *cbdup_userdata;
107 ifapi_policyexec_cbaction cbaction; /**< Callback for policy action */
108 void *cbaction_userdata;
109 } ifapi_policyeval_EXEC_CB;
110
111 /** The states for policy execution */
112 enum IFAPI_STATE_POLICY_EXCECUTE {
113 POLICY_EXECUTE_INIT = 0,
114 POLICY_EXECUTE_FINISH,
115 POLICY_EXECUTE_CALLBACK,
116 POLICY_LOAD_KEY,
117 POLICY_FLUSH_KEY,
118 POLICY_VERIFY,
119 POLICY_AUTH_CALLBACK,
120 POLICY_AUTH_SENT,
121 POLICY_EXEC_ESYS
122 };
123
124 typedef struct IFAPI_POLICY_CALLBACK_CTX IFAPI_POLICY_CALLBACK_CTX;
125
126 /** The context of the policy execution */
127 struct IFAPI_POLICY_EXEC_CTX {
128 enum IFAPI_STATE_POLICY_EXCECUTE state;
129 /**< The execution state of the current
130 policy command */
131 TPML_DIGEST digest_list; /** The digest list of policy or */
132 IFAPI_POLICY_EXEC_CTX *next; /**< Pointer to next policy */
133 IFAPI_POLICY_EXEC_CTX *prev; /**< Pointer to previous policy */
134 ESYS_TR session; /**< The current policy session */
135 TPMS_POLICY *policy;
136 ESYS_TR policySessionSav; /**< Backup policy session */
137 ESYS_TR object_handle;
138 ESYS_TR nv_index;
139 ESYS_TR auth_handle;
140 IFAPI_OBJECT auth_object; /**< Object used for authentication */
141 ESYS_TR auth_session;
142 TPMI_ALG_HASH hash_alg;
143 void *app_data; /**< Application data for policy execution callbacks */
144 NODE_OBJECT_T *policy_elements; /**< The policy elements to be executed */
145 TPM2B_DIGEST *nonceTPM;
146 uint8_t *buffer;
147 size_t buffer_size;
148 TPM2B_NAME name;
149 char *pem_key; /**< Pem key recreated during policy execution */
150 struct POLICY_LIST *policy_list;
151 /**< List of policies for authorization selection */
152 ifapi_policyeval_EXEC_CB callbacks;
153 /**< callbacks used for execution of sub
154 policies and actions which require access
155 to the FAPI context. */
156 };
157
158 TSS2_RC
159 ifapi_policyeval_execute_prepare(
160 IFAPI_POLICY_EXEC_CTX *pol_ctx,
161 TPMI_ALG_HASH hash_alg,
162 TPMS_POLICY *policy);
163
164 TSS2_RC
165 ifapi_policyeval_execute(
166 ESYS_CONTEXT *esys_ctx,
167 IFAPI_POLICY_EXEC_CTX *current_policy);
168
169 #endif /* FAPI_POLICY_EXECUTE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "tss2_mu.h"
14 #include "fapi_util.h"
15 #include "fapi_crypto.h"
16 //#include "fapi_policy.h"
17 #include "ifapi_helpers.h"
18 #include "ifapi_policy_instantiate.h"
19 #include "ifapi_json_deserialize.h"
20 #include "tpm_json_deserialize.h"
21 #define LOGMODULE fapi
22 #include "util/log.h"
23 #include "util/aux_util.h"
24
25 static TSS2_RC
26 get_policy_elements(TPML_POLICYELEMENTS *policy, NODE_OBJECT_T **policy_element_list);
27
28 /** Compute linked list with a list of policy elements which could be instantiated.
29 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
30 */
31 static TSS2_RC
32 get_policy_elements(TPML_POLICYELEMENTS *policy, NODE_OBJECT_T **policy_element_list)
33 {
34 TSS2_RC r = TSS2_RC_SUCCESS;
35 size_t i, j;
36
37 for (i = 0; i < policy->count; i++) {
38 if (policy->elements[i].type == POLICYOR) {
39 /* Policy with sub policies */
40 TPML_POLICYBRANCHES *branches = policy->elements[i].element.PolicyOr.branches;
41 for (j = 0; j < branches->count; j++) {
42 r = get_policy_elements(branches->authorizations[j].policy,
43 policy_element_list);
44 goto_if_error(r, "Get policy elements.", error_cleanup);
45 }
46 } else {
47 r = push_object_to_list(&policy->elements[i], policy_element_list);
48 goto_if_error(r, "Get policy elements.", error_cleanup);
49 }
50 }
51 return r;
52
53 error_cleanup:
54 ifapi_free_node_list(*policy_element_list);
55 return r;
56 }
57
58 /** Prepare instantiation a policy template.
59 *
60 * Parts of policies which are referenced by object paths will be replaced with
61 * the appropriate values of the referenced objects.
62 *
63 * @param[in] context The context storing information for re-entry after try again.
64 * @param[in] policy The policy to be instantiated.
65 * @param[in] callbacks The needed callback functions with the corresponding user data
66 * which will be passed to the callback.
67 * @retval TSS2_RC_SUCCESS on success.
68 * @retval FAPI error codes on failure
69 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
70 */
71 TSS2_RC
72 ifapi_policyeval_instantiate_async(
73 IFAPI_POLICY_EVAL_INST_CTX *context, /* For re-entry after try_again for offsets and such */
74 TPMS_POLICY *policy, /* in */
75 ifapi_policyeval_INST_CB *callbacks)
76 {
77 TSS2_RC r;
78
79 /* Store callbacks and their parameters in context */
80 context->callbacks = *callbacks;
81
82 /* Compute list of all policy elements which have to be instantiated */
83 if (context->policy_elements) {
84 ifapi_free_object_list(context->policy_elements);
85 context->policy_elements = NULL;
86 }
87 r = get_policy_elements(policy->policy, &context->policy_elements);
88 return r;
89 }
90
91 /** Compute name and public information format a PEM key.
92 *
93 * @param[in] keyPEM The key in PEM format.
94 * @param[out] keyPublic The public information of the PEM key.
95 * @param[out] name the name computed from the public information.
96 * @param[in] hash_alg The name alg of the key has to passed.
97 * @retval TSS2_RC_SUCCESS on success.
98 */
99 static TSS2_RC
100 set_pem_key_param(
101 const char *keyPEM,
102 TPMT_PUBLIC *keyPublic,
103 TPM2B_NAME *name,
104 TPMI_ALG_HASH hash_alg)
105 {
106 TSS2_RC r;
107 TPM2B_PUBLIC public;
108
109 if (!keyPEM || strlen(keyPEM) == 0) {
110 /* No PEM key used. Parameters are already set in policy. */
111 return TSS2_RC_SUCCESS;
112 }
113
114 /* Use PEM key to compute public information and name */
115 name->size = 0;
116
117 TPM2_ALG_ID rsaOrEcc = ifapi_get_signature_algorithm_from_pem(keyPEM);
118 r = ifapi_initialize_sign_public(rsaOrEcc, &public);
119 return_if_error(r, "Could not initialize public info of key");
120
121 r = ifapi_get_tpm2b_public_from_pem(keyPEM, &public);
122 return_if_error(r, "Invalid PEM key.");
123
124 *keyPublic = public.publicArea;
125 keyPublic->nameAlg = hash_alg;
126 r = ifapi_get_name(&public.publicArea, name);
127 return_if_error(r, "Compute key name.");
128
129 return TSS2_RC_SUCCESS;
130 }
131
132 #define CHECK_TEMPLATE_PATH(path, template) \
133 if (!path) { \
134 return_error2(TSS2_FAPI_RC_BAD_TEMPLATE, "No path for policy %s", template); \
135 }
136
137 /** Finalize instantiation a policy template.
138 *
139 * All needed asyncroous callbacks will be executed for all policy elements offset
140 * The policy.
141 *
142 * @param[in] context The context storing information for re-entry after try again.
143 * @retval TSS2_RC_SUCCESS on success.
144 * @retval TSS2_FAPI_RC_BAD_TEMPLATE If the templayte is not complete for instantiation.
145 * @retval FAPI error codes on failure
146 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
147 * this function needs to be called again.
148 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
149 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
150 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
151 * the function.
152 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
153 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
154 * operation already pending.
155 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
156 * during authorization.
157 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
158 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
159 * object store.
160 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
161 */
162 TSS2_RC
163 ifapi_policyeval_instantiate_finish(
164 IFAPI_POLICY_EVAL_INST_CTX *context)
165 {
166 TSS2_RC r = TSS2_RC_SUCCESS;
167 NODE_OBJECT_T *first_in_pol_list = context->policy_elements;
168 size_t i_last;
169
170 /* While not all policy elements are instantiated */
171 while (first_in_pol_list) {
172 TPMT_POLICYELEMENT *pol_element = first_in_pol_list->object;
173 switch (pol_element->type) {
174 case POLICYSIGNED:
175 if (pol_element->element.PolicySigned.keyPublic.type) {
176 /* Public info found in template, key path will not be needed. */
177 SAFE_FREE(pol_element->element.PolicySigned.keyPath);
178 break;
179 }
180
181 if (pol_element->element.PolicySigned.keyPEM &&
182 strlen(pol_element->element.PolicySigned.keyPEM) > 0) {
183 /* Determine name and public info for PEM key. */
184 r = set_pem_key_param(pol_element->element.PolicySigned.keyPEM,
185 &pol_element->element.PolicySigned.keyPublic,
186 &pol_element->element.PolicySigned.publicKey,
187 pol_element->element.PolicySigned.keyPEMhashAlg);
188 return_if_error(r, "Set parameter of pem key.");
189
190 /* Clear pem key, will be recreated during execution. */
191 SAFE_FREE(pol_element->element.PolicySigned.keyPEM);
192
193 break;
194 }
195 CHECK_TEMPLATE_PATH(pol_element->element.PolicySigned.keyPath, "PolicySigned");
196
197 /* Public info will be added to policy. */
198 r = context->callbacks.cbpublic(pol_element->element.PolicySigned.keyPath,
199 &pol_element->element.PolicySigned.keyPublic,
200 context->callbacks.cbpublic_userdata);
201 return_try_again(r);
202 return_if_error(r, "read_finish failed");
203 /* Clear keypath, only public data will be needed */
204 SAFE_FREE(pol_element->element.PolicySigned.keyPath);
205
206 break;
207
208 case POLICYNAMEHASH:
209 /* Set index of last name to be computed. */
210 i_last = pol_element->element.PolicyNameHash.count - 1;
211 while (!pol_element->element.PolicyNameHash.objectNames[i_last].size) {
212 /* Not all object names have been computed or were initialized */
213 size_t i = pol_element->element.PolicyNameHash.i;
214 r = context->callbacks.cbname(pol_element->element.PolicyNameHash.namePaths[i],
215 &pol_element->element.PolicyNameHash.objectNames[i],
216 context->callbacks.cbname_userdata);
217 return_try_again(r);
218 return_if_error(r, "get object name.");
219 pol_element->element.PolicyNameHash.i++;
220 SAFE_FREE(pol_element->element.PolicyNameHash.namePaths[i]);
221 }
222 break;
223
224 case POLICYSECRET:
225 if (pol_element->element.PolicySecret.objectName.size) {
226 /* Name found in template, object path will not be needed. */
227 SAFE_FREE(pol_element->element.PolicySecret.objectPath);
228 break;
229 }
230 CHECK_TEMPLATE_PATH(pol_element->element.PolicySecret.objectPath, "PolicySecret");
231 /* Object name will be added to policy. */
232 r = context->callbacks.cbname(pol_element->element.PolicySecret.objectPath,
233 &pol_element->element.PolicySecret.objectName,
234 context->callbacks.cbname_userdata);
235 return_try_again(r);
236 return_if_error(r, "read_finish failed");
237 SAFE_FREE(pol_element->element.PolicySecret.objectPath);
238 break;
239
240 case POLICYPCR:
241 if (pol_element->element.PolicyPCR.pcrs &&
242 pol_element->element.PolicyPCR.pcrs->count) {
243 /* PCR values already defined */
244 break;
245 }
246 /* Current values of PCRs will be used for policy */
247 r = context->callbacks.cbpcr(&pol_element->element.PolicyPCR.currentPCRs,
248 &pol_element->element.PolicyPCR.currentPCRandBanks,
249 &pol_element->element.PolicyPCR.pcrs,
250 context->callbacks.cbpcr_userdata);
251 return_try_again(r);
252 return_if_error(r, "read_finish failed");
253
254 pol_element->element.PolicyPCR.currentPCRs.sizeofSelect = 0;
255 pol_element->element.PolicyPCR.currentPCRandBanks.count = 0;
256 break;
257
258 case POLICYNV:
259 if (pol_element->element.PolicyNV.nvPublic.nvPublic.nvIndex) {
260 /* nvIndex is already set in policy. Path will not be needed */
261 pol_element->element.PolicyNV.nvIndex
262 = pol_element->element.PolicyNV.nvPublic.nvPublic.nvIndex;
263 SAFE_FREE(pol_element->element.PolicyNV.nvPath);
264 break;
265 }
266
267 CHECK_TEMPLATE_PATH(pol_element->element.PolicyNV.nvPath, "PolicyNv");
268 /* Object name will be added to policy. */
269 r = context->callbacks.cbnvpublic(pol_element->element.PolicyNV.nvPath,
270 &pol_element->element.PolicyNV.nvPublic,
271 context->callbacks.cbnvpublic_userdata);
272 return_try_again(r);
273 return_if_error(r, "read_finish failed");
274
275 pol_element->element.PolicyNV.nvIndex
276 = pol_element->element.PolicyNV.nvPublic.nvPublic.nvIndex;
277
278 /* Clear NV path, only public data will be needed */
279 SAFE_FREE(pol_element->element.PolicyNV.nvPath);
280 break;
281
282 case POLICYDUPLICATIONSELECT:
283 if (pol_element->element.PolicyDuplicationSelect.newParentPublic.publicArea.type) {
284 /* public data is already set in policy. Path will not be needed. */
285 SAFE_FREE(pol_element->element.PolicyDuplicationSelect.newParentPath);
286 break;
287 }
288
289 CHECK_TEMPLATE_PATH(pol_element->element.PolicyDuplicationSelect.newParentPath,
290 "PolicyDuplicationselect");
291
292 /* Public info will be added to policy. */
293 r = context->callbacks.cbpublic(
294 pol_element->element.PolicyDuplicationSelect.newParentPath,
295 &pol_element->element.PolicyDuplicationSelect.newParentPublic.publicArea,
296 context->callbacks.cbpublic_userdata);
297 return_try_again(r);
298 return_if_error(r, "read_finish failed");
299
300 r = ifapi_get_name(
301 &pol_element->element.PolicyDuplicationSelect.newParentPublic.publicArea,
302 &pol_element->element.PolicyDuplicationSelect.newParentName);
303 return_if_error(r, "Compute key name");
304
305 /* Clear keypath, only public data will be needed */
306 SAFE_FREE(pol_element->element.PolicyDuplicationSelect.newParentPath);
307 break;
308
309 case POLICYAUTHORIZENV:
310 if (pol_element->element.PolicyAuthorizeNv.nvPublic.nvPublic.nvIndex) {
311 /* nvIndex is already set in policy. Path will not be needed */
312 SAFE_FREE(pol_element->element.PolicyAuthorizeNv.nvPath);
313 break;
314 }
315
316 CHECK_TEMPLATE_PATH(pol_element->element.PolicyAuthorizeNv.nvPath,
317 "PolicyAuthorizeNv");
318 /* Object name will be added to policy. */
319 r = context->callbacks.cbnvpublic(pol_element->element.PolicyAuthorizeNv.nvPath,
320 &pol_element->element.PolicyAuthorizeNv.nvPublic,
321 context->callbacks.cbnvpublic_userdata);
322 return_try_again(r);
323 return_if_error(r, "read_finish failed");
324 /* Clear NV path, only public data will be needed */
325 SAFE_FREE(pol_element->element.PolicyAuthorizeNv.nvPath);
326 break;
327
328 case POLICYAUTHORIZE:
329 if (pol_element->element.PolicyAuthorize.keyPublic.type) {
330 /* Public info found in template, key path will not be needed. */
331 SAFE_FREE(pol_element->element.PolicyAuthorize.keyPath);
332 r = ifapi_get_name(&pol_element->element.PolicyAuthorize.keyPublic,
333 &pol_element->element.PolicyAuthorize.keyName);
334 return_if_error(r, "Compute key name");
335
336 break;
337 }
338
339 if (pol_element->element.PolicyAuthorize.keyPEM &&
340 strlen(pol_element->element.PolicyAuthorize.keyPEM) > 0) {
341 /* Determine name and public info for PEM key. */
342 r = set_pem_key_param(pol_element->element.PolicyAuthorize.keyPEM,
343 &pol_element->element.PolicyAuthorize.keyPublic,
344 &pol_element->element.PolicyAuthorize.keyName,
345 pol_element->element.PolicyAuthorize.keyPEMhashAlg);
346 return_if_error(r, "Set parameter of pem key.");
347
348 pol_element->element.PolicyAuthorize.keyPEM = NULL;
349
350 break;
351 }
352
353 CHECK_TEMPLATE_PATH(pol_element->element.PolicyAuthorize.keyPath, "PolicyAuthorize");
354
355 /* Object public data will be added to policy. */
356 r = context->callbacks.cbpublic(pol_element->element.PolicyAuthorize.keyPath,
357 &pol_element->element.PolicyAuthorize.keyPublic,
358 context->callbacks.cbpublic_userdata);
359 return_try_again(r);
360 return_if_error(r, "read_finish failed");
361
362 /* Compute key name from public info */
363 r = ifapi_get_name(&pol_element->element.PolicyAuthorize.keyPublic,
364 &pol_element->element.PolicyAuthorize.keyName);
365 return_if_error(r, "Compute key name");
366
367 /* Clear key path, only public data will be needed */
368 SAFE_FREE(pol_element->element.PolicyAuthorize.keyPath);
369 break;
370 }
371 /* Cleanup head of list and use next policy element */
372 context->policy_elements = first_in_pol_list->next;
373 SAFE_FREE(first_in_pol_list);
374 }
375 return r;
376 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifndef FAPI_POLICY_INSTANTIATE_H
6 #define FAPI_POLICY_INSTANTIATE_H
7
8 #include <stdint.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <json-c/json.h>
13 #include <json-c/json_util.h>
14
15 #include "tss2_esys.h"
16 #include "tss2_fapi.h"
17 //#include "fapi_int.h"
18 //#include "fapi_policy.h"
19 //#include "ifapi_keystore.h"
20
21 typedef TSS2_RC (*ifapi_policyeval_cbpublic) (
22 const char *path,
23 TPMT_PUBLIC *public,
24 void *userdata); /* e.g. for FAPI_CONTEXT */
25
26 typedef TSS2_RC (*ifapi_policyeval_cbname) (
27 const char *path,
28 TPM2B_NAME *name,
29 void *userdata); /* e.g. for FAPI_CONTEXT */
30
31 typedef TSS2_RC (*ifapi_policyeval_cbnvindex) (
32 const char *path,
33 TPMI_RH_NV_INDEX *nv_index,
34 void *userdata); /* e.g. for FAPI_CONTEXT */
35
36 typedef TSS2_RC (*ifapi_policyeval_cbnvpublic) (
37 const char *path,
38 TPM2B_NV_PUBLIC *nv_public,
39 void *userdata); /* e.g. for FAPI_CONTEXT */
40
41 typedef TSS2_RC (*ifapi_policyeval_cbpemparam) (
42 const char *keyPEM,
43 TPMT_PUBLIC *keyPublic,
44 TPM2B_NAME *name,
45 void *userdata); /* e.g. for FAPI_CONTEXT */
46
47 typedef TSS2_RC (*ifapi_policyeval_cbpcr) (
48 TPMS_PCR_SELECT *pcrSelect,
49 TPML_PCR_SELECTION *pcrBankSelect,
50 TPML_PCRVALUES **pcrs,
51 void *userdata); /* e.g. for FAPI_CONTEXT */
52
53 typedef struct {
54 ifapi_policyeval_cbpcr cbpcr; /**< Callback to compute current PCR value */
55 void *cbpcr_userdata;
56 ifapi_policyeval_cbname cbname; /**< Callback to compute name of an object from path */
57 void *cbname_userdata;
58 ifapi_policyeval_cbpublic cbpublic; /**< Callback to compute public info of a key */
59 void *cbpublic_userdata;
60 ifapi_policyeval_cbnvpublic cbnvpublic; /**< Callback to compute the NV public from path */
61 void *cbnvpublic_userdata;
62 } ifapi_policyeval_INST_CB;
63
64 /** Type for representing the context for policy instantiation.
65 */
66 typedef struct {
67 TPMS_POLICY *policy; /**< The policy to be instantiated */
68 NODE_OBJECT_T *policy_elements; /** The policy elements to be instantiated */
69 ifapi_policyeval_INST_CB callbacks;
70 } IFAPI_POLICY_EVAL_INST_CTX;
71
72 TSS2_RC
73 ifapi_policyeval_instantiate_async(
74 IFAPI_POLICY_EVAL_INST_CTX *context, /* For re-entry after try_again for offsets and such */
75 TPMS_POLICY *policy, /* in */
76 ifapi_policyeval_INST_CB *callbacks);
77 TSS2_RC
78
79 ifapi_policyeval_instantiate_finish(
80 IFAPI_POLICY_EVAL_INST_CTX *context);
81
82 #endif /* FAPI_POLICY_INSTANTIATE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "tpm_json_deserialize.h"
14 #include "ifapi_json_deserialize.h"
15 #include "fapi_policy.h"
16 #define LOGMODULE fapijson
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20 static char *tss_const_prefixes[] = { "TPM2_ALG_", "TPM2_", "TPM_", "TPMA_", "POLICY", NULL };
21
22 /** Get the index of a sub string after a certain prefix.
23 *
24 * The prefixes from table tss_const_prefixes will be used for case
25 * insensitive comparison.
26 *
27 * param[in] token the token with a potential prefix.
28 * @retval the position of the sub string after the prefix.
29 * @retval 0 if no prefix is found.
30 */
31 static int
32 get_token_start_idx(const char *token)
33 {
34 int itoken = 0;
35 char *entry;
36 int i;
37
38 for (i = 0, entry = tss_const_prefixes[0]; entry != NULL;
39 i++, entry = tss_const_prefixes[i]) {
40 if (strncasecmp(token, entry, strlen(entry)) == 0) {
41 itoken += strlen(entry);
42 break;
43 }
44 }
45 return itoken;
46 }
47
48 /** Get number from a string.
49 *
50 * A string which represents a number or hex number (prefix 0x) is converted
51 * to an int64 number.
52 *
53 * param[in] token the string representing the number.
54 * param[out] num the converted number.
55 * @retval true if token represents a number
56 * @retval false if token does not represent a number.
57 */
58 static bool
59 get_number(const char *token, int64_t *num)
60 {
61 int itoken = 0;
62 int pos = 0;
63 if (strncmp(token, "0x", 2) == 0) {
64 itoken = 2;
65 sscanf(&token[itoken], "%"PRIx64"%n", num, &pos);
66 } else {
67 sscanf(&token[itoken], "%"PRId64"%n", num, &pos);
68 }
69 if ((size_t)pos == strlen(token) - itoken)
70 return true;
71 else
72 return false;
73 }
74
75 /** Deserialize a TPMI_POLICYTYPE json object.
76 *
77 * @param[in] jso the json object to be deserialized.
78 * @param[out] out the deserialzed binary object.
79 * @retval TSS2_RC_SUCCESS if the function call was a success.
80 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
81 */
82 TSS2_RC
83 ifapi_json_TPMI_POLICYTYPE_deserialize(json_object *jso, TPMI_POLICYTYPE *out)
84 {
85 LOG_TRACE("call");
86 return ifapi_json_TPMI_POLICYTYPE_deserialize_txt(jso, out);
87 }
88
89 typedef struct {
90 TPMI_POLICYTYPE in;
91 char *name;
92 } IFAPI_TPMI_POLICYTYPE_ASSIGN;
93
94 static IFAPI_TPMI_POLICYTYPE_ASSIGN deserialize_TPMI_POLICYTYPE_tab[] = {
95 { POLICYOR, "Or" },
96 { POLICYSIGNED, "Signed" },
97 { POLICYSECRET, "Secret" },
98 { POLICYPCR, "PCR" },
99 { POLICYLOCALITY, "Locality" },
100 { POLICYNV, "NV" },
101 { POLICYCOUNTERTIMER, "CounterTimer" },
102 { POLICYCOMMANDCODE, "CommandCode" },
103 { POLICYPHYSICALPRESENCE, "PhysicalPresence" },
104 { POLICYCPHASH, "CpHash" },
105 { POLICYNAMEHASH, "NameHash" },
106 { POLICYDUPLICATIONSELECT, "DuplicationSelect" },
107 { POLICYAUTHORIZE, "Authorize" },
108 { POLICYAUTHVALUE, "AuthValue" },
109 { POLICYPASSWORD, "Password" },
110 { POLICYNVWRITTEN, "NvWritten" },
111 { POLICYTEMPLATE, "Template" },
112 { POLICYAUTHORIZENV, "AuthorizeNv" },
113 { POLICYACTION, "Action" },
114 };
115
116 /** Deserialize a json object of type TPMI_POLICYTYPE.
117 *
118 * @param[in] jso the json object to be deserialized.
119 * @param[out] out the deserialzed binary object.
120 * @retval TSS2_RC_SUCCESS if the function call was a success.
121 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
122 */
123 TSS2_RC
124 ifapi_json_TPMI_POLICYTYPE_deserialize_txt(json_object *jso,
125 TPMI_POLICYTYPE *out)
126 {
127 LOG_TRACE("call");
128 const char *token = json_object_get_string(jso);
129 int64_t i64;
130 if (get_number(token, &i64)) {
131 *out = (TPMI_POLICYTYPE) i64;
132 if ((int64_t)*out != i64) {
133 LOG_ERROR("Bad value");
134 return TSS2_FAPI_RC_BAD_VALUE;
135 }
136 return TSS2_RC_SUCCESS;
137
138 } else {
139 int itoken = get_token_start_idx(token);
140 size_t i;
141 size_t n = sizeof(deserialize_TPMI_POLICYTYPE_tab) /
142 sizeof(deserialize_TPMI_POLICYTYPE_tab[0]);
143 size_t size = strlen(token) - itoken;
144 for (i = 0; i < n; i++) {
145 if (strncasecmp(&token[itoken],
146 &deserialize_TPMI_POLICYTYPE_tab[i].name[0],
147 size) == 0) {
148 *out = deserialize_TPMI_POLICYTYPE_tab[i].in;
149 return TSS2_RC_SUCCESS;
150 }
151 }
152 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
153 }
154
155 }
156
157 /** Deserialize a TPMS_POLICYSIGNED json object.
158 *
159 * @param[in] jso the json object to be deserialized.
160 * @param[out] out the deserialzed binary object.
161 * @retval TSS2_RC_SUCCESS if the function call was a success.
162 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
163 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
164 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
165 */
166 TSS2_RC
167 ifapi_json_TPMS_POLICYSIGNED_deserialize(json_object *jso,
168 TPMS_POLICYSIGNED *out)
169 {
170 json_object *jso2;
171 TSS2_RC r;
172 LOG_TRACE("call");
173 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
174 size_t cond_cnt = 0; /**< counter for conditional fields */
175
176 if (!ifapi_get_sub_object(jso, "cpHashA", &jso2)) {
177 memset(&out->cpHashA, 0, sizeof(TPM2B_DIGEST));
178 } else {
179 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->cpHashA);
180 return_if_error(r, "BAD VALUE");
181 }
182
183 if (!ifapi_get_sub_object(jso, "policyRef", &jso2)) {
184 memset(&out->policyRef, 0, sizeof(TPM2B_NONCE));
185 } else {
186 r = ifapi_json_TPM2B_NONCE_deserialize(jso2, &out->policyRef);
187 return_if_error(r, "BAD VALUE");
188 }
189
190 out->expiration = 0;
191
192 if (!ifapi_get_sub_object(jso, "keyPath", &jso2)) {
193 out->keyPath = NULL;
194 } else {
195 cond_cnt++;
196 r = ifapi_json_char_deserialize(jso2, &out->keyPath);
197 return_if_error(r, "BAD VALUE");
198 }
199
200 if (!ifapi_get_sub_object(jso, "keyPublic", &jso2)) {
201 memset(&out->keyPublic, 0, sizeof(TPMT_PUBLIC));
202 } else {
203 cond_cnt++;
204 r = ifapi_json_TPMT_PUBLIC_deserialize(jso2, &out->keyPublic);
205 return_if_error(r, "BAD VALUE");
206 }
207
208 if (!ifapi_get_sub_object(jso, "keyPEM", &jso2)) {
209 out->keyPEM = NULL;
210 } else {
211 cond_cnt++;
212 r = ifapi_json_char_deserialize(jso2, &out->keyPEM);
213 return_if_error(r, "BAD VALUE");
214 }
215
216 if (!ifapi_get_sub_object(jso, "publicKeyHint", &jso2)) {
217 out->publicKeyHint = NULL;
218 } else {
219 r = ifapi_json_char_deserialize(jso2, &out->publicKeyHint);
220 return_if_error(r, "BAD VALUE");
221 }
222
223 if (!ifapi_get_sub_object(jso, "keyPEMhashAlg", &jso2)) {
224 out->keyPEMhashAlg = TPM2_ALG_SHA256;
225 } else {
226 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->keyPEMhashAlg);
227 return_if_error(r, "BAD VALUE");
228 }
229
230 /* Check whether only one condition field found in policy. */
231 if (cond_cnt != 1) {
232 return_error(TSS2_FAPI_RC_BAD_VALUE,
233 "Exactly one conditional is allowed for policy signed.");
234 }
235
236 LOG_TRACE("true");
237 return TSS2_RC_SUCCESS;
238 }
239
240 /** Deserialize a TPMS_POLICYSECRET json object.
241 *
242 * @param[in] jso the json object to be deserialized.
243 * @param[out] out the deserialzed binary object.
244 * @retval TSS2_RC_SUCCESS if the function call was a success.
245 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
246 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
247 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
248 */
249 TSS2_RC
250 ifapi_json_TPMS_POLICYSECRET_deserialize(json_object *jso,
251 TPMS_POLICYSECRET *out)
252 {
253 json_object *jso2;
254 TSS2_RC r;
255 size_t cond_cnt = 0; /**< counter for conditional fields */
256
257 LOG_TRACE("call");
258 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
259
260 if (!ifapi_get_sub_object(jso, "cpHashA", &jso2)) {
261 memset(&out->cpHashA, 0, sizeof(TPM2B_DIGEST));
262 } else {
263 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->cpHashA);
264 return_if_error(r, "BAD VALUE");
265 }
266
267 if (!ifapi_get_sub_object(jso, "policyRef", &jso2)) {
268 memset(&out->policyRef, 0, sizeof(TPM2B_NONCE));
269 } else {
270 r = ifapi_json_TPM2B_NONCE_deserialize(jso2, &out->policyRef);
271 return_if_error(r, "BAD VALUE");
272 }
273 out->expiration = 0;
274
275 if (!ifapi_get_sub_object(jso, "objectPath", &jso2)) {
276 out->objectPath = NULL;
277 } else {
278 cond_cnt++;
279 r = ifapi_json_char_deserialize(jso2, &out->objectPath);
280 return_if_error(r, "BAD VALUE");
281 }
282
283 if (!ifapi_get_sub_object(jso, "objectName", &jso2)) {
284 memset(&out->objectName, 0, sizeof(TPM2B_DIGEST));
285 } else {
286 cond_cnt++;
287 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->objectName);
288 return_if_error(r, "BAD VALUE");
289 }
290 if (cond_cnt != 1) {
291 return_error(TSS2_FAPI_RC_BAD_VALUE,
292 "Exactly one conditional needed for policy secret .");
293 }
294 LOG_TRACE("true");
295 return TSS2_RC_SUCCESS;
296 }
297
298 /** Deserialize a TPMS_POLICYLOCALITY json object.
299 *
300 * @param[in] jso the json object to be deserialized.
301 * @param[out] out the deserialzed binary object.
302 * @retval TSS2_RC_SUCCESS if the function call was a success.
303 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
304 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
305 */
306 TSS2_RC
307 ifapi_json_TPMS_POLICYLOCALITY_deserialize(json_object *jso,
308 TPMS_POLICYLOCALITY *out)
309 {
310 json_object *jso2;
311 TSS2_RC r;
312 LOG_TRACE("call");
313 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
314
315 if (!ifapi_get_sub_object(jso, "locality", &jso2)) {
316 LOG_ERROR("Bad value");
317 return TSS2_FAPI_RC_BAD_VALUE;
318 }
319 r = ifapi_json_TPMA_LOCALITY_deserialize(jso2, &out->locality);
320 return_if_error(r, "BAD VALUE");
321 LOG_TRACE("true");
322 return TSS2_RC_SUCCESS;
323 }
324
325 /** Deserialize a TPMS_POLICYNV json object.
326 *
327 * @param[in] jso the json object to be deserialized.
328 * @param[out] out the deserialzed binary object.
329 * @retval TSS2_RC_SUCCESS if the function call was a success.
330 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
331 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
332 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
333 */
334 TSS2_RC
335 ifapi_json_TPMS_POLICYNV_deserialize(json_object *jso, TPMS_POLICYNV *out)
336 {
337 json_object *jso2;
338 TSS2_RC r;
339 size_t cond_cnt = 0; /**< counter for conditional fields */
340
341 LOG_TRACE("call");
342 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
343
344 if (!ifapi_get_sub_object(jso, "nvPath", &jso2)) {
345 out->nvPath = NULL;
346 } else {
347 cond_cnt++;
348 r = ifapi_json_char_deserialize(jso2, &out->nvPath);
349 return_if_error(r, "BAD VALUE");
350 }
351
352 if (!ifapi_get_sub_object(jso, "nvIndex", &jso2)) {
353 out->nvIndex = 0;
354 } else {
355 cond_cnt++;
356 r = ifapi_json_TPMI_RH_NV_INDEX_deserialize(jso2, &out->nvIndex);
357 return_if_error(r, "BAD VALUE");
358 }
359
360 if (!ifapi_get_sub_object(jso, "nvPublic", &jso2)) {
361 memset(&out->nvPublic, 0, sizeof(TPM2B_NV_PUBLIC));
362 } else {
363 r = ifapi_json_TPM2B_NV_PUBLIC_deserialize(jso2, &out->nvPublic);
364 return_if_error(r, "BAD VALUE");
365 }
366
367 if (!ifapi_get_sub_object(jso, "operandB", &jso2)) {
368 LOG_ERROR("Bad value");
369 return TSS2_FAPI_RC_BAD_VALUE;
370 }
371 r = ifapi_json_TPM2B_OPERAND_deserialize(jso2, &out->operandB);
372 return_if_error(r, "BAD VALUE");
373
374 if (!ifapi_get_sub_object(jso, "offset", &jso2)) {
375 out->offset = 0;
376 } else {
377 r = ifapi_json_UINT16_deserialize(jso2, &out->offset);
378 return_if_error(r, "BAD VALUE");
379 }
380
381 if (!ifapi_get_sub_object(jso, "operation", &jso2)) {
382 out->operation = 0;
383 } else {
384 r = ifapi_json_TPM2_EO_deserialize(jso2, &out->operation);
385 return_if_error(r, "BAD VALUE");
386 }
387 /* Check whether only one conditional is used. */
388 if (cond_cnt != 1) {
389 return_error(TSS2_FAPI_RC_BAD_VALUE,
390 "Exactly one conditional is allowed for policy NV.");
391 }
392
393 LOG_TRACE("true");
394 return TSS2_RC_SUCCESS;
395 }
396
397 /** Deserialize a TPMS_POLICYCOUNTERTIMER json object.
398 *
399 * @param[in] jso the json object to be deserialized.
400 * @param[out] out the deserialzed binary object.
401 * @retval TSS2_RC_SUCCESS if the function call was a success.
402 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
403 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
404 */
405 TSS2_RC
406 ifapi_json_TPMS_POLICYCOUNTERTIMER_deserialize(json_object *jso,
407 TPMS_POLICYCOUNTERTIMER *out)
408 {
409 json_object *jso2;
410 TSS2_RC r;
411 LOG_TRACE("call");
412 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
413
414 if (!ifapi_get_sub_object(jso, "operandB", &jso2)) {
415 LOG_ERROR("Bad value");
416 return TSS2_FAPI_RC_BAD_VALUE;
417 }
418 r = ifapi_json_TPM2B_OPERAND_deserialize(jso2, &out->operandB);
419 return_if_error(r, "BAD VALUE");
420
421 if (!ifapi_get_sub_object(jso, "offset", &jso2)) {
422 out->offset = 0;
423 } else {
424 r = ifapi_json_UINT16_deserialize(jso2, &out->offset);
425 return_if_error(r, "BAD VALUE");
426 }
427
428 if (!ifapi_get_sub_object(jso, "operation", &jso2)) {
429 LOG_ERROR("Bad value");
430 return TSS2_FAPI_RC_BAD_VALUE;
431 }
432 r = ifapi_json_TPM2_EO_deserialize(jso2, &out->operation);
433 return_if_error(r, "BAD VALUE");
434 LOG_TRACE("true");
435 return TSS2_RC_SUCCESS;
436 }
437
438 /** Deserialize a TPMS_POLICYCOMMANDCODE json object.
439 *
440 * @param[in] jso the json object to be deserialized.
441 * @param[out] out the deserialzed binary object.
442 * @retval TSS2_RC_SUCCESS if the function call was a success.
443 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
444 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
445 */
446 TSS2_RC
447 ifapi_json_TPMS_POLICYCOMMANDCODE_deserialize(json_object *jso,
448 TPMS_POLICYCOMMANDCODE *out)
449 {
450 json_object *jso2;
451 TSS2_RC r;
452 LOG_TRACE("call");
453 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
454
455 if (!ifapi_get_sub_object(jso, "code", &jso2)) {
456 LOG_ERROR("Bad value");
457 return TSS2_FAPI_RC_BAD_VALUE;
458 }
459 r = ifapi_json_TPM2_CC_deserialize(jso2, &out->code);
460 return_if_error(r, "BAD VALUE");
461 LOG_TRACE("true");
462 return TSS2_RC_SUCCESS;
463 }
464
465 /** Deserialize a TPMS_POLICYPHYSICALPRESENCE json object.
466 *
467 * @param[in] jso the json object to be deserialized.
468 * @param[out] out the deserialzed binary object.
469 * @retval TSS2_RC_SUCCESS if the function call was a success.
470 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
471 */
472 TSS2_RC
473 ifapi_json_TPMS_POLICYPHYSICALPRESENCE_deserialize(json_object *jso,
474 TPMS_POLICYPHYSICALPRESENCE *out)
475 {
476 LOG_TRACE("call");
477 (void)jso;
478 (void)out;
479
480 LOG_TRACE("true");
481 return TSS2_RC_SUCCESS;
482 }
483
484 /** Deserialize a TPMS_POLICYCPHASH json object.
485 *
486 * @param[in] jso the json object to be deserialized.
487 * @param[out] out the deserialzed binary object.
488 * @retval TSS2_RC_SUCCESS if the function call was a success.
489 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
490 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
491 */
492 TSS2_RC
493 ifapi_json_TPMS_POLICYCPHASH_deserialize(json_object *jso,
494 TPMS_POLICYCPHASH *out)
495 {
496 json_object *jso2;
497 TSS2_RC r;
498 LOG_TRACE("call");
499 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
500
501 if (!ifapi_get_sub_object(jso, "cpHash", &jso2)) {
502 LOG_ERROR("Bad value");
503 return TSS2_FAPI_RC_BAD_VALUE;
504 }
505 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->cpHash);
506 return_if_error(r, "BAD VALUE");
507 LOG_TRACE("true");
508 return TSS2_RC_SUCCESS;
509 }
510
511 /** Deserialize a TPMS_POLICYNAMEHASH json object.
512 *
513 * @param[in] jso the json object to be deserialized.
514 * @param[out] out the deserialzed binary object.
515 * @retval TSS2_RC_SUCCESS if the function call was a success.
516 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
517 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
518 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
519 */
520 TSS2_RC
521 ifapi_json_TPMS_POLICYNAMEHASH_deserialize(json_object *jso,
522 TPMS_POLICYNAMEHASH *out)
523 {
524 json_object *jso2, *jso3;
525 TSS2_RC r;
526 size_t i, n_paths = 0, n_names = 0;
527 size_t cond_cnt = 0; /**< counter for conditional fields */
528
529 LOG_TRACE("call");
530 memset(out, 0, sizeof(TPMS_POLICYNAMEHASH));
531 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
532
533 if (ifapi_get_sub_object(jso, "nameHash", &jso2)) {
534 cond_cnt++;
535 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->nameHash);
536 return_if_error(r, "BAD VALUE");
537
538 /* No need to deserialize namePaths or objectNames from which nameHash would
539 be derived. */
540 return TSS2_RC_SUCCESS;
541 }
542
543 if (ifapi_get_sub_object(jso, "namePaths", &jso2)) {
544 json_type jso_type = json_object_get_type(jso2);
545 cond_cnt++;
546 if (jso_type == json_type_array) {
547 n_paths = json_object_array_length(jso2);
548 if (n_paths > 3) {
549 return_error(TSS2_FAPI_RC_BAD_VALUE,
550 "More than 3 path names in policy name hash.");
551 }
552 for (i = 0; i < n_paths; i++) {
553 jso3 = json_object_array_get_idx(jso2, i);
554 r = ifapi_json_char_deserialize(jso3, &out->namePaths[i]);
555 return_if_error(r, "BAD VALUE");
556 }
557 out->count = n_paths;
558 } else {
559 LOG_ERROR("No list of name paths");
560 return TSS2_FAPI_RC_BAD_VALUE;
561 }
562
563 }
564 if (ifapi_get_sub_object(jso, "objectNames", &jso2)) {
565 json_type jso_type = json_object_get_type(jso);
566 if (jso_type == json_type_array) {
567 n_names = json_object_array_length(jso2);
568 if (n_paths > 0 && n_names > 0) {
569 return_error(TSS2_FAPI_RC_BAD_VALUE,
570 "Only pathname or only TPM names are allowed "
571 "for policy name hash.");
572 }
573 if (n_names > 3) {
574 return_error(TSS2_FAPI_RC_BAD_VALUE,
575 "More than 3 names in policy name hash.");
576 }
577 for (i = 0; i < n_names; i++) {
578 jso3 = json_object_array_get_idx(jso, i);
579 r = ifapi_json_TPM2B_NAME_deserialize(jso3, &out->objectNames[i]);
580 return_if_error(r, "BAD TEMPLATE");
581 }
582 out->count = n_names;
583 } else {
584 LOG_ERROR("No list of object names");
585 return TSS2_FAPI_RC_BAD_VALUE;
586 }
587 }
588 if (out->count == 0) {
589 LOG_ERROR("No list of object names or path names");
590 return TSS2_FAPI_RC_BAD_VALUE;
591 }
592 /* Check whether only one condition field found in policy. */
593 if (cond_cnt != 1) {
594 return_error(TSS2_FAPI_RC_BAD_VALUE,
595 "Exactly one conditional is allowed for policy name hash.");
596 }
597 return TSS2_RC_SUCCESS;
598 }
599
600 /** Deserialize a TPMS_POLICYDUPLICATIONSELECT json object.
601 *
602 * @param[in] jso the json object to be deserialized.
603 * @param[out] out the deserialzed binary object.
604 * @retval TSS2_RC_SUCCESS if the function call was a success.
605 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
606 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
607 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
608 */
609 TSS2_RC
610 ifapi_json_TPMS_POLICYDUPLICATIONSELECT_deserialize(json_object *jso,
611 TPMS_POLICYDUPLICATIONSELECT *out)
612 {
613 json_object *jso2;
614 TSS2_RC r;
615 size_t cond_cnt = 0; /**< counter for conditional fields */
616
617 LOG_TRACE("call");
618 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
619
620 GET_OPTIONAL(objectName, "objectName", TPM2B_NAME);
621 GET_OPTIONAL(newParentName, "newParentName", TPM2B_NAME);
622 if (out->newParentName.size)
623 cond_cnt++;
624 if (ifapi_get_sub_object(jso, "includeObject", &jso2)) {
625 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->includeObject);
626 return_if_error(r, "Yes or No expected.");
627 } else {
628 if (out->objectName.size > 0)
629 out->includeObject = TPM2_YES;
630 else
631 out->includeObject = TPM2_NO;
632 }
633 GET_OPTIONAL(newParentPublic, "newParentPublic", TPM2B_PUBLIC);
634 if (out->newParentPublic.size)
635 cond_cnt++;
636
637 if (!ifapi_get_sub_object(jso, "newParentPath", &jso2)) {
638 if (!out->newParentPublic.publicArea.type) {
639 return_error(TSS2_FAPI_RC_BAD_VALUE, "No path and TPM2B_PUBLIC");
640 }
641 out->newParentPath = NULL;
642 } else {
643 cond_cnt++;
644 r = ifapi_json_char_deserialize(jso2, &out->newParentPath);
645 return_if_error(r, "BAD VALUE");
646 }
647 /* Check whether only one condition field found in policy. */
648 if (cond_cnt != 1) {
649 return_error(TSS2_FAPI_RC_BAD_VALUE,
650 "Exactly one conditional is allowed for "
651 "policy duplication select.");
652 }
653 LOG_TRACE("true");
654 return TSS2_RC_SUCCESS;
655 }
656
657 /** Deserialize a TPMS_POLICYAUTHORIZE json object.
658 *
659 * @param[in] jso the json object to be deserialized.
660 * @param[out] out the deserialzed binary object.
661 * @retval TSS2_RC_SUCCESS if the function call was a success.
662 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
663 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
664 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
665 */
666 TSS2_RC
667 ifapi_json_TPMS_POLICYAUTHORIZE_deserialize(json_object *jso,
668 TPMS_POLICYAUTHORIZE *out)
669 {
670 json_object *jso2;
671 TSS2_RC r;
672 size_t cond_cnt = 0; /**< counter for conditional fields */
673
674 LOG_TRACE("call");
675 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
676
677 if (!ifapi_get_sub_object(jso, "approvedPolicy", &jso2)) {
678 memset(&out->approvedPolicy, 0, sizeof(TPM2B_DIGEST));
679 } else {
680 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->approvedPolicy);
681 return_if_error(r, "BAD VALUE");
682 }
683
684 if (!ifapi_get_sub_object(jso, "policyRef", &jso2)) {
685 memset(&out->policyRef, 0, sizeof(TPM2B_NONCE));
686 } else {
687 r = ifapi_json_TPM2B_NONCE_deserialize(jso2, &out->policyRef);
688 return_if_error(r, "BAD VALUE");
689 }
690
691 if (!ifapi_get_sub_object(jso, "keyName", &jso2)) {
692 memset(&out->keyName, 0, sizeof(TPM2B_NAME));
693 } else {
694 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->keyName);
695 return_if_error(r, "BAD VALUE");
696 }
697
698 if (!ifapi_get_sub_object(jso, "checkTicket", &jso2)) {
699 memset(&out->checkTicket, 0, sizeof(TPMT_TK_VERIFIED));
700 } else {
701 r = ifapi_json_TPMT_TK_VERIFIED_deserialize(jso2, &out->checkTicket);
702 return_if_error(r, "BAD VALUE");
703 }
704
705 if (ifapi_get_sub_object(jso, "keyPath", &jso2)) {
706 cond_cnt++;
707 r = ifapi_json_char_deserialize(jso2, &out->keyPath);
708 return_if_error(r, "BAD VALUE");
709 } else {
710 out->keyPath = NULL;
711 }
712
713 if (!ifapi_get_sub_object(jso, "keyPublic", &jso2)) {
714 memset(&out->keyPublic, 0, sizeof(TPMT_PUBLIC));
715 } else {
716 cond_cnt++;
717 r = ifapi_json_TPMT_PUBLIC_deserialize(jso2, &out->keyPublic);
718 return_if_error(r, "BAD VALUE");
719 }
720
721 if (!ifapi_get_sub_object(jso, "keyPEM", &jso2)) {
722 out->keyPEM = NULL;
723 } else {
724 cond_cnt++;
725 r = ifapi_json_char_deserialize(jso2, &out->keyPEM);
726 return_if_error(r, "BAD VALUE");
727 }
728
729 if (!ifapi_get_sub_object(jso, "keyPEMhashAlg", &jso2)) {
730 out->keyPEMhashAlg = 0;
731 } else {
732 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->keyPEMhashAlg);
733 return_if_error(r, "BAD VALUE");
734 }
735 /* Check whether only one condition field found in policy. */
736 if (cond_cnt != 1) {
737 return_error(TSS2_FAPI_RC_BAD_VALUE,
738 "Exactly one conditional is allowed for policy authorize.");
739 }
740 LOG_TRACE("true");
741 return TSS2_RC_SUCCESS;
742 }
743
744 /** Deserialize a TPMS_POLICYAUTHVALUE json object.
745 *
746 * @param[in] jso the json object to be deserialized.
747 * @param[out] out the deserialzed binary object.
748 * @retval TSS2_RC_SUCCESS if the function call was a success.
749 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
750 */
751 TSS2_RC
752 ifapi_json_TPMS_POLICYAUTHVALUE_deserialize(json_object *jso,
753 TPMS_POLICYAUTHVALUE *out)
754 {
755 LOG_TRACE("call");
756 (void)out;
757 (void)jso;
758
759 LOG_TRACE("true");
760 return TSS2_RC_SUCCESS;
761 }
762
763 /** Deserialize a TPMS_POLICYPASSWORD json object.
764 *
765 * @param[in] jso the json object to be deserialized.
766 * @param[out] out the deserialzed binary object.
767 * @retval TSS2_RC_SUCCESS if the function call was a success.
768 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
769 */
770 TSS2_RC
771 ifapi_json_TPMS_POLICYPASSWORD_deserialize(json_object *jso,
772 TPMS_POLICYPASSWORD *out)
773 {
774 LOG_TRACE("call");
775 (void)jso;
776 (void)out;
777
778 LOG_TRACE("true");
779 return TSS2_RC_SUCCESS;
780 }
781
782 /** Deserialize a TPMS_POLICYNVWRITTEN json object.
783 *
784 * @param[in] jso the json object to be deserialized.
785 * @param[out] out the deserialzed binary object.
786 * @retval TSS2_RC_SUCCESS if the function call was a success.
787 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
788 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
789 */
790 TSS2_RC
791 ifapi_json_TPMS_POLICYNVWRITTEN_deserialize(json_object *jso,
792 TPMS_POLICYNVWRITTEN *out)
793 {
794 json_object *jso2;
795 TSS2_RC r;
796 LOG_TRACE("call");
797 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
798
799 if (!ifapi_get_sub_object(jso, "writtenSet", &jso2)) {
800 out->writtenSet = TPM2_YES;
801 return TSS2_RC_SUCCESS;
802 }
803 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->writtenSet);
804 return_if_error(r, "BAD VALUE");
805 LOG_TRACE("true");
806 return TSS2_RC_SUCCESS;
807 }
808
809 /** Deserialize a TPMS_POLICYTEMPLATE json object.
810 *
811 * @param[in] jso the json object to be deserialized.
812 * @param[out] out the deserialzed binary object.
813 * @retval TSS2_RC_SUCCESS if the function call was a success.
814 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
815 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
816 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
817 */
818 TSS2_RC
819 ifapi_json_TPMS_POLICYTEMPLATE_deserialize(json_object *jso,
820 TPMS_POLICYTEMPLATE *out)
821 {
822 json_object *jso2;
823 TSS2_RC r;
824 size_t cond_cnt = 0; /**< counter for conditional fields */
825
826 LOG_TRACE("call");
827 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
828
829 if (!ifapi_get_sub_object(jso, "templateHash", &jso2)) {
830 memset(&out->templateHash, 0, sizeof(TPM2B_DIGEST));
831 } else {
832 cond_cnt++;
833 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->templateHash);
834 return_if_error(r, "BAD VALUE");
835 }
836
837 if (!ifapi_get_sub_object(jso, "templatePublic", &jso2)) {
838 memset(&out->templatePublic, 0, sizeof(TPM2B_PUBLIC));
839 } else {
840 cond_cnt++;
841 r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->templatePublic);
842 return_if_error(r, "BAD VALUE");
843 }
844
845 if (ifapi_get_sub_object(jso, "templateName", &jso2)) {
846 r = ifapi_json_char_deserialize(jso2, &out->templateName);
847 return_if_error(r, "BAD VALUE");
848 } else {
849 out->templateName = NULL;
850 }
851
852 /* Check whether only one condition field found in policy. */
853 if (cond_cnt != 1) {
854 return_error(TSS2_FAPI_RC_BAD_VALUE,
855 "Exactly one conditional is allowed for policy template.");
856 }
857
858 LOG_TRACE("true");
859 return TSS2_RC_SUCCESS;
860 }
861
862 /** Deserialize a TPMS_POLICYAUTHORIZENV json object.
863 *
864 * @param[in] jso the json object to be deserialized.
865 * @param[out] out the deserialzed binary object.
866 * @retval TSS2_RC_SUCCESS if the function call was a success.
867 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
868 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
869 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
870 */
871 TSS2_RC
872 ifapi_json_TPMS_POLICYAUTHORIZENV_deserialize(json_object *jso,
873 TPMS_POLICYAUTHORIZENV *out)
874 {
875 json_object *jso2;
876 TSS2_RC r;
877 size_t cond_cnt = 0; /**< counter for conditional fields */
878
879 LOG_TRACE("call");
880 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
881
882 memset(out, 0, sizeof(TPMS_POLICYAUTHORIZENV));
883
884 if (ifapi_get_sub_object(jso, "nvPath", &jso2)) {
885 cond_cnt++;
886 r = ifapi_json_char_deserialize(jso2, &out->nvPath);
887 return_if_error(r, "BAD VALUE");
888 } else {
889 out->nvPath = NULL;
890 }
891
892 if (!ifapi_get_sub_object(jso, "nvPublic", &jso2)) {
893 memset(&out->nvPublic, 0, sizeof(TPM2B_NV_PUBLIC));
894 } else {
895 cond_cnt++;
896 r = ifapi_json_TPM2B_NV_PUBLIC_deserialize(jso2, &out->nvPublic);
897 return_if_error(r, "BAD VALUE");
898 }
899 /* Check whether only one condition field found in policy. */
900 if (cond_cnt != 1) {
901 return_error(TSS2_FAPI_RC_BAD_VALUE,
902 "Exactly one conditional is allowed for policy signed.");
903 }
904
905 LOG_TRACE("true");
906 return TSS2_RC_SUCCESS;
907 }
908
909 /** Deserialize a TPMS_POLICYACTION json object.
910 *
911 * @param[in] jso the json object to be deserialized.
912 * @param[out] out the deserialzed binary object.
913 * @retval TSS2_RC_SUCCESS if the function call was a success.
914 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
915 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
916 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
917 */
918 TSS2_RC
919 ifapi_json_TPMS_POLICYACTION_deserialize(json_object *jso,
920 TPMS_POLICYACTION *out)
921 {
922 json_object *jso2;
923 TSS2_RC r;
924 LOG_TRACE("call");
925 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
926
927 memset(out, 0, sizeof(*out));
928
929 if (!ifapi_get_sub_object(jso, "action", &jso2)) {
930 LOG_ERROR("Bad value");
931 return TSS2_FAPI_RC_BAD_VALUE;
932 }
933 r = ifapi_json_char_deserialize(jso2, &out->action);
934 return_if_error(r, "BAD VALUE");
935 LOG_TRACE("true");
936 return TSS2_RC_SUCCESS;
937 }
938
939 /** Deserialize a TPMS_PCRVALUE json object.
940 *
941 * @param[in] jso the json object to be deserialized.
942 * @param[out] out the deserialzed binary object.
943 * @retval TSS2_RC_SUCCESS if the function call was a success.
944 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
945 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
946 */
947 TSS2_RC
948 ifapi_json_TPMS_PCRVALUE_deserialize(json_object *jso, TPMS_PCRVALUE *out)
949 {
950 json_object *jso2;
951 TSS2_RC r;
952
953 LOG_TRACE("call");
954 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
955
956 if (!ifapi_get_sub_object(jso, "pcr", &jso2)) {
957 LOG_ERROR("Bad value");
958 return TSS2_FAPI_RC_BAD_VALUE;
959 }
960 r = ifapi_json_UINT32_deserialize(jso2, &out->pcr);
961 return_if_error(r, "BAD VALUE");
962
963 if (!ifapi_get_sub_object(jso, "hashAlg", &jso2)) {
964 LOG_ERROR("Bad value");
965 return TSS2_FAPI_RC_BAD_VALUE;
966 }
967 r = ifapi_json_TPM2_ALG_ID_deserialize(jso2, &out->hashAlg);
968 return_if_error(r, "BAD VALUE");
969 if (!ifapi_get_sub_object(jso, "digest", &jso2)) {
970 LOG_ERROR("BAD VALUE");
971 return TSS2_FAPI_RC_BAD_VALUE;
972 }
973 r = ifapi_json_TPMU_HA_deserialize(out->hashAlg, jso2, &out->digest);
974 return_if_error(r, "BAD VALUE");
975
976 LOG_TRACE("true");
977 return TSS2_RC_SUCCESS;
978 }
979
980 /** Deserialize a TPML_PCRVALUES json object.
981 *
982 * @param[in] jso the json object to be deserialized.
983 * @param[out] out the deserialzed binary object.
984 * @retval TSS2_RC_SUCCESS if the function call was a success.
985 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
986 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
987 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
988 */
989 TSS2_RC
990 ifapi_json_TPML_PCRVALUES_deserialize(json_object *jso, TPML_PCRVALUES **out)
991 {
992 json_object *jso2;
993 TSS2_RC r;
994 LOG_TRACE("call");
995 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
996
997 json_type jso_type = json_object_get_type(jso);
998 if (jso_type == json_type_array) {
999 *out = calloc(1, sizeof(TPML_PCRVALUES) +
1000 json_object_array_length(jso) * sizeof(TPMS_PCRVALUE));
1001 return_if_null(*out, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1002
1003 (*out)->count = json_object_array_length(jso);
1004 for (size_t i = 0; i < (*out)->count; i++) {
1005 jso2 = json_object_array_get_idx(jso, i);
1006 r = ifapi_json_TPMS_PCRVALUE_deserialize(jso2, &(*out)->pcrs[i]);
1007 return_if_error(r, "TPMS_PCRVALUE_deserialize");
1008 }
1009 } else {
1010 return_error(TSS2_FAPI_RC_BAD_VALUE, "BAD VALUE");
1011 }
1012 return TSS2_RC_SUCCESS;
1013 }
1014
1015 /** Deserialize a TPMS_POLICYPCR json object.
1016 *
1017 * @param[in] jso the json object to be deserialized.
1018 * @param[out] out the deserialzed binary object.
1019 * @retval TSS2_RC_SUCCESS if the function call was a success.
1020 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1021 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1022 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1023 */
1024 TSS2_RC
1025 ifapi_json_TPMS_POLICYPCR_deserialize(json_object *jso, TPMS_POLICYPCR *out)
1026 {
1027 json_object *jso2;
1028 TSS2_RC r;
1029 size_t cond_cnt = 0; /**< counter for conditional fields */
1030
1031 LOG_TRACE("call");
1032 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1033
1034 if (ifapi_get_sub_object(jso, "pcrs", &jso2)) {
1035 cond_cnt++;
1036 r = ifapi_json_TPML_PCRVALUES_deserialize(jso2, &out->pcrs);
1037 return_if_error(r, "BAD VALUE");
1038 } else {
1039 memset(&out->pcrs, 0, sizeof(TPML_PCRVALUES));
1040 }
1041
1042 if (ifapi_get_sub_object(jso, "currentPCRs", &jso2)) {
1043 cond_cnt++;
1044 r = ifapi_json_TPMS_PCR_SELECT_deserialize(jso2, &out->currentPCRs);
1045 return_if_error(r, "BAD VALUE");
1046 } else {
1047 memset(&out->currentPCRs, 0, sizeof(TPMS_PCR_SELECT));
1048 }
1049
1050 if (ifapi_get_sub_object(jso, "currentPCRandBanks", &jso2)) {
1051 cond_cnt++;
1052 r = ifapi_json_TPML_PCR_SELECTION_deserialize(jso2, &out->currentPCRandBanks);
1053 return_if_error(r, "BAD VALUE");
1054 } else {
1055 memset(&out->currentPCRandBanks, 0, sizeof(TPML_PCR_SELECTION));
1056 }
1057
1058 /* Check whether only one conditional is used. */
1059 if (cond_cnt != 1) {
1060 return_error(TSS2_FAPI_RC_BAD_VALUE,
1061 "Exactly one conditional is allowed for policy PCR.");
1062 }
1063
1064 LOG_TRACE("true");
1065 return TSS2_RC_SUCCESS;
1066 }
1067
1068 /** Deserialize a TPMS_POLICYAUTHORIZATION json object.
1069 *
1070 * @param[in] jso the json object to be deserialized.
1071 * @param[out] out the deserialzed binary object.
1072 * @retval TSS2_RC_SUCCESS if the function call was a success.
1073 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1074 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1075 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1076 */
1077 TSS2_RC
1078 ifapi_json_TPMS_POLICYAUTHORIZATION_deserialize(json_object *jso,
1079 TPMS_POLICYAUTHORIZATION *out)
1080 {
1081 json_object *jso2;
1082 TSS2_RC r;
1083 LOG_TRACE("call");
1084 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1085
1086 if (!ifapi_get_sub_object(jso, "type", &jso2)) {
1087 LOG_ERROR("Bad value");
1088 return TSS2_FAPI_RC_BAD_VALUE;
1089 }
1090 r = ifapi_json_char_deserialize(jso2, &out->type);
1091 return_if_error(r, "BAD VALUE");
1092
1093 if (!ifapi_get_sub_object(jso, "key", &jso2)) {
1094 LOG_ERROR("Bad value");
1095 return TSS2_FAPI_RC_BAD_VALUE;
1096 }
1097 r = ifapi_json_TPMT_PUBLIC_deserialize(jso2, &out->key);
1098 return_if_error(r, "BAD VALUE");
1099
1100 if (!ifapi_get_sub_object(jso, "policyRef", &jso2)) {
1101 LOG_ERROR("Bad value");
1102 return TSS2_FAPI_RC_BAD_VALUE;
1103 }
1104 r = ifapi_json_TPM2B_NONCE_deserialize(jso2, &out->policyRef);
1105 return_if_error(r, "BAD VALUE");
1106
1107 if (!ifapi_get_sub_object(jso, "signature", &jso2)) {
1108 LOG_ERROR("Bad value");
1109 return TSS2_FAPI_RC_BAD_VALUE;
1110 }
1111 r = ifapi_json_TPMT_SIGNATURE_deserialize(jso2, &out->signature);
1112 return_if_error(r, "BAD VALUE");
1113 LOG_TRACE("true");
1114 return TSS2_RC_SUCCESS;
1115 }
1116
1117 /** Deserialize a TPML_POLICYAUTHORIZATIONS json object.
1118 *
1119 * @param[in] jso the json object to be deserialized.
1120 * @param[out] out the deserialzed binary object.
1121 * @retval TSS2_RC_SUCCESS if the function call was a success.
1122 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1123 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1124 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1125 */
1126 TSS2_RC
1127 ifapi_json_TPML_POLICYAUTHORIZATIONS_deserialize(json_object *jso,
1128 TPML_POLICYAUTHORIZATIONS **out)
1129 {
1130 json_object *jso2;
1131 TSS2_RC r = TSS2_RC_SUCCESS;
1132 LOG_TRACE("call");
1133 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1134
1135 json_type jso_type = json_object_get_type(jso);
1136 if (jso_type == json_type_array) {
1137 *out = calloc(1, sizeof(TPML_POLICYAUTHORIZATIONS) +
1138 json_object_array_length(jso) * sizeof(TPMS_POLICYAUTHORIZATION));
1139 return_if_null(*out, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1140
1141 (*out)->count = json_object_array_length(jso);
1142 for (size_t i = 0; i < (*out)->count; i++) {
1143 jso2 = json_object_array_get_idx(jso, i);
1144 r = ifapi_json_TPMS_POLICYAUTHORIZATION_deserialize(jso2,
1145 &(*out)->authorizations[i]);
1146 return_if_error(r, "TPMS_POLICYAUTHORIZATION_deserialize");
1147 }
1148 } else {
1149 return_error(TSS2_FAPI_RC_BAD_VALUE, "BAD VALUE");
1150 }
1151 return TSS2_RC_SUCCESS;
1152 }
1153
1154 /** Deserialize a TPMS_POLICYBRANCH json object.
1155 *
1156 * @param[in] jso the json object to be deserialized.
1157 * @param[out] out the deserialzed binary object.
1158 * @retval TSS2_RC_SUCCESS if the function call was a success.
1159 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1160 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1161 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1162 */
1163 TSS2_RC
1164 ifapi_json_TPMS_POLICYBRANCH_deserialize(json_object *jso,
1165 TPMS_POLICYBRANCH *out)
1166 {
1167 json_object *jso2;
1168 TSS2_RC r;
1169 LOG_TRACE("call");
1170 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1171
1172 if (!ifapi_get_sub_object(jso, "name", &jso2)) {
1173 LOG_ERROR("Bad value");
1174 return TSS2_FAPI_RC_BAD_VALUE;
1175 }
1176 r = ifapi_json_char_deserialize(jso2, &out->name);
1177 return_if_error(r, "BAD VALUE");
1178
1179 if (!ifapi_get_sub_object(jso, "description", &jso2)) {
1180 LOG_ERROR("Bad value");
1181 return TSS2_FAPI_RC_BAD_VALUE;
1182 }
1183 r = ifapi_json_char_deserialize(jso2, &out->description);
1184 return_if_error(r, "BAD VALUE");
1185
1186 if (!ifapi_get_sub_object(jso, "policy", &jso2)) {
1187 LOG_ERROR("Bad value");
1188 return TSS2_FAPI_RC_BAD_VALUE;
1189 }
1190 r = ifapi_json_TPML_POLICYELEMENTS_deserialize(jso2, &out->policy);
1191 return_if_error(r, "BAD VALUE");
1192
1193 if (!ifapi_get_sub_object(jso, "policyDigests", &jso2)) {
1194 memset(&out->policyDigests, 0, sizeof(TPML_DIGEST_VALUES));
1195 } else {
1196 r = ifapi_json_TPML_DIGEST_VALUES_deserialize(jso2, &out->policyDigests);
1197 return_if_error(r, "BAD VALUE");
1198
1199 }
1200
1201 LOG_TRACE("true");
1202 return TSS2_RC_SUCCESS;
1203 }
1204
1205 /** Deserialize a TPML_POLICYBRANCHES json object.
1206 *
1207 * @param[in] jso the json object to be deserialized.
1208 * @param[out] out the deserialzed binary object.
1209 * @retval TSS2_RC_SUCCESS if the function call was a success.
1210 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1211 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1212 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1213 */
1214 TSS2_RC
1215 ifapi_json_TPML_POLICYBRANCHES_deserialize(json_object *jso,
1216 TPML_POLICYBRANCHES **out)
1217 {
1218 json_object *jso2;
1219 TSS2_RC r;
1220 LOG_TRACE("call");
1221 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1222
1223 json_type jso_type = json_object_get_type(jso);
1224 if (jso_type == json_type_array) {
1225 *out = calloc(1, sizeof(TPML_POLICYBRANCHES) +
1226 json_object_array_length(jso) * sizeof(TPMS_POLICYBRANCH));
1227 return_if_null(*out, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1228
1229 (*out)->count = json_object_array_length(jso);
1230 for (size_t i = 0; i < (*out)->count; i++) {
1231 jso2 = json_object_array_get_idx(jso, i);
1232 r = ifapi_json_TPMS_POLICYBRANCH_deserialize(jso2, &(*out)->authorizations[i]);
1233 return_if_error(r, "TPMS_POLICYBRANCH_deserialize");
1234 }
1235 } else {
1236 return_error(TSS2_FAPI_RC_BAD_VALUE, "BAD VALUE");
1237 }
1238 return TSS2_RC_SUCCESS;
1239 }
1240
1241 /** Deserialize a TPMS_POLICYOR json object.
1242 *
1243 * @param[in] jso the json object to be deserialized.
1244 * @param[out] out the deserialzed binary object.
1245 * @retval TSS2_RC_SUCCESS if the function call was a success.
1246 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1247 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1248 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1249 */
1250 TSS2_RC
1251 ifapi_json_TPMS_POLICYOR_deserialize(json_object *jso, TPMS_POLICYOR *out)
1252 {
1253 json_object *jso2;
1254 TSS2_RC r;
1255 LOG_TRACE("call");
1256 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1257
1258 if (!ifapi_get_sub_object(jso, "branches", &jso2)) {
1259 LOG_ERROR("Bad value");
1260 return TSS2_FAPI_RC_BAD_VALUE;
1261 }
1262 r = ifapi_json_TPML_POLICYBRANCHES_deserialize(jso2, &out->branches);
1263 return_if_error(r, "BAD VALUE");
1264 LOG_TRACE("true");
1265 return TSS2_RC_SUCCESS;
1266 }
1267
1268 /** Deserialize a TPMU_POLICYELEMENT json object.
1269 *
1270 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
1271 * @param[in] selector The type the policy element.
1272 * @param[in] jso the json object to be deserialized.
1273 * @param[out] out the deserialzed binary object.
1274 * @retval TSS2_RC_SUCCESS if the function call was a success.
1275 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1276 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1277 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1278 */
1279 TSS2_RC
1280 ifapi_json_TPMU_POLICYELEMENT_deserialize(
1281 UINT32 selector,
1282 json_object *jso,
1283 TPMU_POLICYELEMENT *out)
1284 {
1285 LOG_TRACE("call");
1286 switch (selector) {
1287 case POLICYOR:
1288 return ifapi_json_TPMS_POLICYOR_deserialize(jso, &out->PolicyOr);
1289 case POLICYSIGNED:
1290 return ifapi_json_TPMS_POLICYSIGNED_deserialize(jso, &out->PolicySigned);
1291 case POLICYSECRET:
1292 return ifapi_json_TPMS_POLICYSECRET_deserialize(jso, &out->PolicySecret);
1293 case POLICYPCR:
1294 return ifapi_json_TPMS_POLICYPCR_deserialize(jso, &out->PolicyPCR);
1295 case POLICYLOCALITY:
1296 return ifapi_json_TPMS_POLICYLOCALITY_deserialize(jso, &out->PolicyLocality);
1297 case POLICYNV:
1298 return ifapi_json_TPMS_POLICYNV_deserialize(jso, &out->PolicyNV);
1299 case POLICYCOUNTERTIMER:
1300 return ifapi_json_TPMS_POLICYCOUNTERTIMER_deserialize(jso,
1301 &out->PolicyCounterTimer);
1302 case POLICYCOMMANDCODE:
1303 return ifapi_json_TPMS_POLICYCOMMANDCODE_deserialize(jso,
1304 &out->PolicyCommandCode);
1305 case POLICYPHYSICALPRESENCE:
1306 return ifapi_json_TPMS_POLICYPHYSICALPRESENCE_deserialize(jso,
1307 &out->PolicyPhysicalPresence);
1308 case POLICYCPHASH:
1309 return ifapi_json_TPMS_POLICYCPHASH_deserialize(jso, &out->PolicyCpHash);
1310 case POLICYNAMEHASH:
1311 return ifapi_json_TPMS_POLICYNAMEHASH_deserialize(jso, &out->PolicyNameHash);
1312 case POLICYDUPLICATIONSELECT:
1313 return ifapi_json_TPMS_POLICYDUPLICATIONSELECT_deserialize(jso,
1314 &out->PolicyDuplicationSelect);
1315 case POLICYAUTHORIZE:
1316 return ifapi_json_TPMS_POLICYAUTHORIZE_deserialize(jso, &out->PolicyAuthorize);
1317 case POLICYAUTHVALUE:
1318 return ifapi_json_TPMS_POLICYAUTHVALUE_deserialize(jso, &out->PolicyAuthValue);
1319 case POLICYPASSWORD:
1320 return ifapi_json_TPMS_POLICYPASSWORD_deserialize(jso, &out->PolicyPassword);
1321 case POLICYNVWRITTEN:
1322 return ifapi_json_TPMS_POLICYNVWRITTEN_deserialize(jso, &out->PolicyNvWritten);
1323 case POLICYTEMPLATE:
1324 return ifapi_json_TPMS_POLICYTEMPLATE_deserialize(jso, &out->PolicyTemplate);
1325 case POLICYAUTHORIZENV:
1326 return ifapi_json_TPMS_POLICYAUTHORIZENV_deserialize(jso,
1327 &out->PolicyAuthorizeNv);
1328 case POLICYACTION:
1329 return ifapi_json_TPMS_POLICYACTION_deserialize(jso, &out->PolicyAction);
1330 default:
1331 LOG_TRACE("false");
1332 return TSS2_FAPI_RC_BAD_VALUE;
1333 };
1334 }
1335
1336 /** Deserialize a TPMT_POLICYELEMENT json object.
1337 *
1338 * @param[in] jso the json object to be deserialized.
1339 * @param[out] out the deserialzed binary object.
1340 * @retval TSS2_RC_SUCCESS if the function call was a success.
1341 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1342 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1343 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1344 */
1345 TSS2_RC
1346 ifapi_json_TPMT_POLICYELEMENT_deserialize(json_object *jso,
1347 TPMT_POLICYELEMENT *out)
1348 {
1349 json_object *jso2;
1350 TSS2_RC r;
1351 LOG_TRACE("call");
1352 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1353
1354 if (!ifapi_get_sub_object(jso, "type", &jso2)) {
1355 LOG_ERROR("Bad value");
1356 return TSS2_FAPI_RC_BAD_VALUE;
1357 }
1358 r = ifapi_json_TPMI_POLICYTYPE_deserialize(jso2, &out->type);
1359 return_if_error(r, "BAD VALUE");
1360
1361 if (!ifapi_get_sub_object(jso, "policyDigests", &jso2)) {
1362 memset(&out->policyDigests, 0, sizeof(TPML_DIGEST_VALUES));
1363 } else {
1364 r = ifapi_json_TPML_DIGEST_VALUES_deserialize(jso2, &out->policyDigests);
1365 return_if_error(r, "BAD VALUE");
1366
1367 }
1368 r = ifapi_json_TPMU_POLICYELEMENT_deserialize(out->type, jso, &out->element);
1369 return_if_error(r, "BAD VALUE");
1370
1371 LOG_TRACE("true");
1372 return TSS2_RC_SUCCESS;
1373 }
1374
1375 /** Deserialize a TPML_POLICYELEMENTS json object.
1376 *
1377 * @param[in] jso the json object to be deserialized.
1378 * @param[out] out the deserialzed binary object.
1379 * @retval TSS2_RC_SUCCESS if the function call was a success.
1380 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1381 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1382 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1383 */
1384 TSS2_RC
1385 ifapi_json_TPML_POLICYELEMENTS_deserialize(json_object *jso,
1386 TPML_POLICYELEMENTS **out)
1387 {
1388 json_object *jso2;
1389 TSS2_RC r;
1390 LOG_TRACE("call");
1391 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1392
1393 json_type jso_type = json_object_get_type(jso);
1394 if (jso_type == json_type_array) {
1395 *out = calloc(1, sizeof(TPML_POLICYELEMENTS) +
1396 json_object_array_length(jso) * sizeof(TPMT_POLICYELEMENT));
1397 return_if_null(*out, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1398
1399 (*out)->count = json_object_array_length(jso);
1400 for (size_t i = 0; i < (*out)->count; i++) {
1401 jso2 = json_object_array_get_idx(jso, i);
1402 r = ifapi_json_TPMT_POLICYELEMENT_deserialize(jso2, &(*out)->elements[i]);
1403 return_if_error(r, "TPMT_POLICYELEMENT_deserialize");
1404 }
1405 } else {
1406 return_error(TSS2_FAPI_RC_BAD_VALUE, "BAD VALUE");
1407 }
1408 return TSS2_RC_SUCCESS;
1409 }
1410
1411 /** Deserialize a TPMS_POLICY json object.
1412 *
1413 * @param[in] jso the json object to be deserialized.
1414 * @param[out] out the deserialzed binary object.
1415 * @retval TSS2_RC_SUCCESS if the function call was a success.
1416 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1417 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1418 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1419 */
1420 TSS2_RC
1421 ifapi_json_TPMS_POLICY_deserialize(json_object *jso,
1422 TPMS_POLICY *out)
1423 {
1424 json_object *jso2;
1425 TSS2_RC r;
1426 LOG_TRACE("call");
1427 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1428
1429 if (!ifapi_get_sub_object(jso, "description", &jso2)) {
1430 LOG_ERROR("No description for policy.");
1431 return TSS2_FAPI_RC_BAD_VALUE;
1432 }
1433 r = ifapi_json_char_deserialize(jso2, &out->description);
1434 return_if_error(r, "BAD VALUE");
1435
1436 if (!ifapi_get_sub_object(jso, "policyDigests", &jso2)) {
1437 memset(&out->policyDigests, 0, sizeof(TPML_DIGEST_VALUES));
1438 } else {
1439 r = ifapi_json_TPML_DIGEST_VALUES_deserialize(jso2, &out->policyDigests);
1440 return_if_error(r, "BAD VALUE");
1441
1442 }
1443 if (!ifapi_get_sub_object(jso, "policyAuthorizations", &jso2)) {
1444 memset(&out->policyAuthorizations, 0, sizeof(TPML_POLICYAUTHORIZATIONS));
1445 } else {
1446 r = ifapi_json_TPML_POLICYAUTHORIZATIONS_deserialize(jso2,
1447 &out->policyAuthorizations);
1448 return_if_error(r, "BAD VALUE");
1449
1450 }
1451 if (!ifapi_get_sub_object(jso, "policy", &jso2)) {
1452 LOG_ERROR("Bad value");
1453 return TSS2_FAPI_RC_BAD_VALUE;
1454 }
1455 r = ifapi_json_TPML_POLICYELEMENTS_deserialize(jso2, &out->policy);
1456 return_if_error(r, "BAD VALUE");
1457 LOG_TRACE("true");
1458 return TSS2_RC_SUCCESS;
1459 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef IFAPI_POLICY_JSON_DESERIALIZE_H
6 #define IFAPI_POLICY_JSON_DESERIALIZE_H
7
8 #include <stdbool.h>
9 #include <json-c/json.h>
10 #include <json-c/json_util.h>
11
12 #include "tss2_tpm2_types.h"
13 #include "fapi_int.h"
14
15 TSS2_RC
16 ifapi_json_TPMI_POLICYTYPE_deserialize(json_object *jso, TPMI_POLICYTYPE *out);
17
18 TSS2_RC
19 ifapi_json_TPMI_POLICYTYPE_deserialize_txt(json_object *jso,
20 TPMI_POLICYTYPE *out);
21
22 TSS2_RC
23 ifapi_json_TPMS_POLICYSIGNED_deserialize(json_object *jso,
24 TPMS_POLICYSIGNED *out);
25
26 TSS2_RC
27 ifapi_json_TPMS_POLICYSECRET_deserialize(json_object *jso,
28 TPMS_POLICYSECRET *out);
29
30 TSS2_RC
31 ifapi_json_TPMS_POLICYLOCALITY_deserialize(json_object *jso,
32 TPMS_POLICYLOCALITY *out);
33
34 TSS2_RC
35 ifapi_json_TPMS_POLICYNV_deserialize(json_object *jso, TPMS_POLICYNV *out);
36
37 TSS2_RC
38 ifapi_json_TPMS_POLICYCOUNTERTIMER_deserialize(json_object *jso,
39 TPMS_POLICYCOUNTERTIMER *out);
40
41 TSS2_RC
42 ifapi_json_TPMS_POLICYCOMMANDCODE_deserialize(json_object *jso,
43 TPMS_POLICYCOMMANDCODE *out);
44
45 TSS2_RC
46 ifapi_json_TPMS_POLICYPHYSICALPRESENCE_deserialize(json_object *jso,
47 TPMS_POLICYPHYSICALPRESENCE *out);
48
49 TSS2_RC
50 ifapi_json_TPMS_POLICYCPHASH_deserialize(json_object *jso,
51 TPMS_POLICYCPHASH *out);
52
53 TSS2_RC
54 ifapi_json_TPMS_POLICYNAMEHASH_deserialize(json_object *jso,
55 TPMS_POLICYNAMEHASH *out);
56
57 TSS2_RC
58 ifapi_json_TPMS_POLICYDUPLICATIONSELECT_deserialize(json_object *jso,
59 TPMS_POLICYDUPLICATIONSELECT *out);
60
61 TSS2_RC
62 ifapi_json_TPMS_POLICYAUTHORIZE_deserialize(json_object *jso,
63 TPMS_POLICYAUTHORIZE *out);
64
65 TSS2_RC
66 ifapi_json_TPMS_POLICYAUTHVALUE_deserialize(json_object *jso,
67 TPMS_POLICYAUTHVALUE *out);
68
69 TSS2_RC
70 ifapi_json_TPMS_POLICYPASSWORD_deserialize(json_object *jso,
71 TPMS_POLICYPASSWORD *out);
72
73 TSS2_RC
74 ifapi_json_TPMS_POLICYNVWRITTEN_deserialize(json_object *jso,
75 TPMS_POLICYNVWRITTEN *out);
76
77 TSS2_RC
78 ifapi_json_TPMS_POLICYTEMPLATE_deserialize(json_object *jso,
79 TPMS_POLICYTEMPLATE *out);
80
81 TSS2_RC
82 ifapi_json_TPMS_POLICYAUTHORIZENV_deserialize(json_object *jso,
83 TPMS_POLICYAUTHORIZENV *out);
84
85 TSS2_RC
86 ifapi_json_TPMS_POLICYACTION_deserialize(json_object *jso,
87 TPMS_POLICYACTION *out);
88
89 TSS2_RC
90 ifapi_json_TPMS_PCRVALUE_deserialize(json_object *jso, TPMS_PCRVALUE *out);
91
92 TSS2_RC
93 ifapi_json_TPML_PCRVALUES_deserialize(json_object *jso, TPML_PCRVALUES **out);
94
95 TSS2_RC
96 ifapi_json_TPMS_POLICYPCR_deserialize(json_object *jso, TPMS_POLICYPCR *out);
97
98 TSS2_RC
99 ifapi_json_TPMS_POLICYAUTHORIZATION_deserialize(json_object *jso,
100 TPMS_POLICYAUTHORIZATION *out);
101
102 TSS2_RC
103 ifapi_json_TPML_POLICYAUTHORIZATIONS_deserialize(json_object *jso,
104 TPML_POLICYAUTHORIZATIONS **out);
105
106 TSS2_RC
107 ifapi_json_TPMS_POLICYBRANCH_deserialize(json_object *jso,
108 TPMS_POLICYBRANCH *out);
109
110 TSS2_RC
111 ifapi_json_TPML_POLICYBRANCHES_deserialize(json_object *jso,
112 TPML_POLICYBRANCHES **out);
113
114 TSS2_RC
115 ifapi_json_TPMS_POLICYOR_deserialize(json_object *jso, TPMS_POLICYOR *out);
116
117 TSS2_RC
118 ifapi_json_TPMU_POLICYELEMENT_deserialize(UINT32 selector, json_object *jso,
119 TPMU_POLICYELEMENT *out);
120
121 TSS2_RC
122 ifapi_json_TPMT_POLICYELEMENT_deserialize(json_object *jso,
123 TPMT_POLICYELEMENT *out);
124
125 TSS2_RC
126 ifapi_json_TPML_POLICYELEMENTS_deserialize(json_object *jso,
127 TPML_POLICYELEMENTS **out);
128
129 TSS2_RC
130 ifapi_json_TPMS_POLICY_deserialize(json_object *jso,
131 TPMS_POLICY *out);
132
133 #endif /* IFAPI_POLICY_JSON_DESERIALIZE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <stdio.h>
10
11 #include "tpm_json_serialize.h"
12 #include "fapi_policy.h"
13 #include "ifapi_policy_json_serialize.h"
14
15 #define LOGMODULE fapijson
16 #include "util/log.h"
17 #include "util/aux_util.h"
18
19
20 /** Serialize a character string to json.
21 *
22 * @param[in]in the character string.
23 * @param[out] out the json object.
24 * @retval TSS2_RC_SUCCESS if the function call was a success.
25 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
26 */
27 static TSS2_RC
28 ifapi_json_char_serialize(
29 const char *in,
30 json_object **jso)
31 {
32 if (in == NULL) {
33 *jso = json_object_new_string("");
34 } else {
35 *jso = json_object_new_string(in);
36 }
37 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
38 return TSS2_RC_SUCCESS;
39 }
40
41 typedef struct {
42 TPMI_POLICYTYPE in;
43 char *name;
44 } TPMI_POLICYTYPE_ASSIGN;
45
46 static TPMI_POLICYTYPE_ASSIGN serialize_TPMI_POLICYTYPE_tab[] = {
47 { POLICYOR, "POLICYOR" },
48 { POLICYSIGNED, "POLICYSIGNED" },
49 { POLICYSECRET, "POLICYSECRET" },
50 { POLICYPCR, "POLICYPCR" },
51 { POLICYLOCALITY, "POLICYLOCALITY" },
52 { POLICYNV, "POLICYNV" },
53 { POLICYCOUNTERTIMER, "POLICYCOUNTERTIMER" },
54 { POLICYCOMMANDCODE, "POLICYCOMMANDCODE" },
55 { POLICYPHYSICALPRESENCE, "POLICYPHYSICALPRESENCE" },
56 { POLICYCPHASH, "POLICYCPHASH" },
57 { POLICYNAMEHASH, "POLICYNAMEHASH" },
58 { POLICYDUPLICATIONSELECT, "POLICYDUPLICATIONSELECT" },
59 { POLICYAUTHORIZE, "POLICYAUTHORIZE" },
60 { POLICYAUTHVALUE, "POLICYAUTHVALUE" },
61 { POLICYPASSWORD, "POLICYPASSWORD" },
62 { POLICYNVWRITTEN, "POLICYNVWRITTEN" },
63 { POLICYTEMPLATE, "POLICYTEMPLATE" },
64 { POLICYAUTHORIZENV, "POLICYAUTHORIZENV" },
65 { POLICYACTION, "POLICYACTION" },
66 };
67
68 /** Get json object for a constant, if a variable is actually of type TPMI_POLICYTYPE.
69 *
70 * @param[in] in binary value of constant.
71 * @param[out] str_jso with text representing the constant.
72 * @retval TSS2_RC_SUCCESS if the function call was a success.
73 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
74 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPMI_POLICYTYPE.
75 */
76 TSS2_RC
77 ifapi_json_TPMI_POLICYTYPE_serialize_txt(
78 const TPMI_POLICYTYPE in,
79 json_object **str_jso)
80 {
81 size_t n = sizeof(serialize_TPMI_POLICYTYPE_tab) / sizeof(
82 serialize_TPMI_POLICYTYPE_tab[0]);
83 size_t i;
84 for (i = 0; i < n; i++) {
85 if (serialize_TPMI_POLICYTYPE_tab[i].in == in) {
86 *str_jso = json_object_new_string(serialize_TPMI_POLICYTYPE_tab[i].name);
87 return_if_null(str_jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
88
89 return TSS2_RC_SUCCESS;
90 }
91 }
92 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
93 }
94
95 /** Serialize TPMI_POLICYTYPE to json.
96 *
97 * @param[in] in constant to be serialized.
98 * @param[out] jso pointer to the json object.
99 * @retval TSS2_RC_SUCCESS if the function call was a success.
100 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
101 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPMI_POLICYTYPE.
102 */
103 TSS2_RC
104 ifapi_json_TPMI_POLICYTYPE_serialize(const TPMI_POLICYTYPE in,
105 json_object **jso)
106 {
107 return ifapi_json_TPMI_POLICYTYPE_serialize_txt(in, jso);
108 }
109
110 /** Serialize value of type TPMS_POLICYSIGNED to json.
111 *
112 * @param[in] in value to be serialized.
113 * @param[out] jso pointer to the json object.
114 * @retval TSS2_RC_SUCCESS if the function call was a success.
115 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
116 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYSIGNED.
117 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
118 */
119 TSS2_RC
120 ifapi_json_TPMS_POLICYSIGNED_serialize(const TPMS_POLICYSIGNED *in,
121 json_object **jso)
122 {
123 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
124
125 TSS2_RC r;
126 json_object *jso2;
127 size_t cond_cnt = 0; /**< counter for conditional fields */
128
129 if (*jso == NULL)
130 *jso = json_object_new_object();
131
132 if (in->cpHashA.size != 0) {
133 jso2 = NULL;
134 r = ifapi_json_TPM2B_DIGEST_serialize(&in->cpHashA, &jso2);
135 return_if_error(r, "Serialize TPM2B_DIGEST");
136
137 json_object_object_add(*jso, "cpHashA", jso2);
138 }
139 if (in->policyRef.size != 0) {
140 jso2 = NULL;
141 r = ifapi_json_TPM2B_NONCE_serialize(&in->policyRef, &jso2);
142 return_if_error(r, "Serialize TPM2B_NONCE");
143
144 json_object_object_add(*jso, "policyRef", jso2);
145 }
146 if (in->keyPath && strlen(in->keyPath) > 0) {
147 jso2 = NULL;
148 cond_cnt++;
149 r = ifapi_json_char_serialize(in->keyPath, &jso2);
150 return_if_error(r, "Serialize char");
151
152 json_object_object_add(*jso, "keyPath", jso2);
153 }
154 if (in->keyPublic.type != 0) {
155 jso2 = NULL;
156 cond_cnt++;
157 r = ifapi_json_TPMT_PUBLIC_serialize(&in->keyPublic, &jso2);
158 return_if_error(r, "Serialize TPMT_PUBLIC");
159
160 json_object_object_add(*jso, "keyPublic", jso2);
161 }
162 if ((in->keyPEM) && strcmp(in->keyPEM, "") != 0) {
163 jso2 = NULL;
164 cond_cnt++;
165 r = ifapi_json_char_serialize(in->keyPEM, &jso2);
166 return_if_error(r, "Serialize char");
167
168 json_object_object_add(*jso, "keyPEM", jso2);
169 }
170 if ((in->publicKeyHint) && strcmp(in->publicKeyHint, "") != 0) {
171 jso2 = NULL;
172 r = ifapi_json_char_serialize(in->publicKeyHint, &jso2);
173 return_if_error(r, "Serialize char");
174
175 json_object_object_add(*jso, "publicKeyHint", jso2);
176 }
177 if (in->keyPEMhashAlg != 0) {
178 jso2 = NULL;
179 r = ifapi_json_TPMI_ALG_HASH_serialize(in->keyPEMhashAlg, &jso2);
180 return_if_error(r, "Serialize TPMI_ALG_HASH");
181
182 json_object_object_add(*jso, "keyPEMhashAlg", jso2);
183 }
184 /* Check whether only one conditional is used. */
185 if (cond_cnt != 1) {
186 return_error(TSS2_FAPI_RC_BAD_VALUE,
187 "Exactly one conditional is allowed for policy signed.");
188 }
189 return TSS2_RC_SUCCESS;
190 }
191
192 /** Serialize value of type TPMS_POLICYSECRET to json.
193 *
194 * @param[in] in value to be serialized.
195 * @param[out] jso pointer to the json object.
196 * @retval TSS2_RC_SUCCESS if the function call was a success.
197 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
198 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYSECRET.
199 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
200 */
201 TSS2_RC
202 ifapi_json_TPMS_POLICYSECRET_serialize(const TPMS_POLICYSECRET *in,
203 json_object **jso)
204 {
205 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
206
207 TSS2_RC r;
208 json_object *jso2;
209 size_t cond_cnt = 0; /**< counter for conditional fields */
210
211 if (*jso == NULL)
212 *jso = json_object_new_object();
213 jso2 = NULL;
214 r = ifapi_json_TPM2B_NONCE_serialize(&in->nonceTPM, &jso2);
215 return_if_error(r, "Serialize TPM2B_NONCE");
216
217 json_object_object_add(*jso, "nonceTPM", jso2);
218 jso2 = NULL;
219 r = ifapi_json_TPM2B_DIGEST_serialize(&in->cpHashA, &jso2);
220 return_if_error(r, "Serialize TPM2B_DIGEST");
221
222 json_object_object_add(*jso, "cpHashA", jso2);
223 if (in->policyRef.size != 0) {
224 jso2 = NULL;
225 r = ifapi_json_TPM2B_NONCE_serialize(&in->policyRef, &jso2);
226 return_if_error(r, "Serialize TPM2B_NONCE");
227
228 json_object_object_add(*jso, "policyRef", jso2);
229 }
230 jso2 = NULL;
231 r = ifapi_json_INT32_serialize(in->expiration, &jso2);
232 return_if_error(r, "Serialize INT32");
233
234 json_object_object_add(*jso, "expiration", jso2);
235 if ((in->objectPath) && strcmp(in->objectPath, "") != 0) {
236 jso2 = NULL;
237 cond_cnt++;
238 r = ifapi_json_char_serialize(in->objectPath, &jso2);
239 return_if_error(r, "Serialize char");
240
241 json_object_object_add(*jso, "objectPath", jso2);
242 }
243 if (in->objectName.size != 0) {
244 jso2 = NULL;
245 cond_cnt++;
246 r = ifapi_json_TPM2B_NAME_serialize(&in->objectName, &jso2);
247 return_if_error(r, "Serialize TPM2B_DIGEST");
248
249 json_object_object_add(*jso, "objectName", jso2);
250 }
251 if (cond_cnt != 1) {
252 return_error(TSS2_FAPI_RC_BAD_VALUE,
253 "Exactly one conditional needed for policy secret .");
254 }
255 return TSS2_RC_SUCCESS;
256 }
257
258 /** Serialize value of type TPMS_POLICYLOCALITY to json.
259 *
260 * @param[in] in value to be serialized.
261 * @param[out] jso pointer to the json object.
262 * @retval TSS2_RC_SUCCESS if the function call was a success.
263 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
264 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYLOCALITY.
265 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
266 */
267 TSS2_RC
268 ifapi_json_TPMS_POLICYLOCALITY_serialize(const TPMS_POLICYLOCALITY *in,
269 json_object **jso)
270 {
271 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
272
273 TSS2_RC r;
274 json_object *jso2;
275
276 if (*jso == NULL)
277 *jso = json_object_new_object();
278 jso2 = NULL;
279 r = ifapi_json_TPMA_LOCALITY_serialize(in->locality, &jso2);
280 return_if_error(r, "Serialize TPMA_LOCALITY");
281
282 json_object_object_add(*jso, "locality", jso2);
283 return TSS2_RC_SUCCESS;
284 }
285
286 /** Serialize value of type TPMS_POLICYNV to json.
287 *
288 * @param[in] in value to be serialized.
289 * @param[out] jso pointer to the json object.
290 * @retval TSS2_RC_SUCCESS if the function call was a success.
291 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
292 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYNV.
293 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
294 */
295 TSS2_RC
296 ifapi_json_TPMS_POLICYNV_serialize(const TPMS_POLICYNV *in, json_object **jso)
297 {
298 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
299
300 TSS2_RC r;
301 json_object *jso2;
302 size_t cond_cnt = 0; /**< counter for conditional fields */
303
304 if (*jso == NULL)
305 *jso = json_object_new_object();
306 if ((in->nvPath) && strcmp(in->nvPath, "") != 0) {
307 jso2 = NULL;
308 cond_cnt++;
309 r = ifapi_json_char_serialize(in->nvPath, &jso2);
310 return_if_error(r, "Serialize char");
311
312 json_object_object_add(*jso, "nvPath", jso2);
313 }
314 if (in->nvIndex != 0) {
315 jso2 = NULL;
316 cond_cnt++;
317 r = ifapi_json_TPMI_RH_NV_INDEX_serialize(in->nvIndex, &jso2);
318 return_if_error(r, "Serialize TPMI_RH_NV_INDEX");
319
320 json_object_object_add(*jso, "nvIndex", jso2);
321 }
322
323 if (in->nvPublic.nvPublic.nvIndex) {
324 jso2 = NULL;
325 r = ifapi_json_TPM2B_NV_PUBLIC_serialize(&in->nvPublic, &jso2);
326 return_if_error(r, "Serialize TPM2B_NV_PUBLIC");
327
328 json_object_object_add(*jso, "nvPublic", jso2);
329 }
330
331 jso2 = NULL;
332 r = ifapi_json_TPM2B_OPERAND_serialize(&in->operandB, &jso2);
333 return_if_error(r, "Serialize TPM2B_OPERAND");
334
335 json_object_object_add(*jso, "operandB", jso2);
336 if (in->offset != 0) {
337 jso2 = NULL;
338 r = ifapi_json_UINT16_serialize(in->offset, &jso2);
339 return_if_error(r, "Serialize UINT16");
340
341 json_object_object_add(*jso, "offset", jso2);
342 }
343 if (in->operation != 0) {
344 jso2 = NULL;
345 r = ifapi_json_TPM2_EO_serialize(in->operation, &jso2);
346 return_if_error(r, "Serialize TPM2_EO");
347
348 json_object_object_add(*jso, "operation", jso2);
349 }
350 /* Check whether only one conditional is used. */
351 if (cond_cnt != 1) {
352 return_error(TSS2_FAPI_RC_BAD_VALUE,
353 "Exactly one conditional is allowed for policy NV.");
354 }
355
356 return TSS2_RC_SUCCESS;
357 }
358
359 /** Serialize value of type TPMS_POLICYCOUNTERTIMER to json.
360 *
361 * @param[in] in value to be serialized.
362 * @param[out] jso pointer to the json object.
363 * @retval TSS2_RC_SUCCESS if the function call was a success.
364 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
365 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYCOUNTERTIMER.
366 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
367 */
368 TSS2_RC
369 ifapi_json_TPMS_POLICYCOUNTERTIMER_serialize(const TPMS_POLICYCOUNTERTIMER *in,
370 json_object **jso)
371 {
372 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
373
374 TSS2_RC r;
375 json_object *jso2;
376
377 if (*jso == NULL)
378 *jso = json_object_new_object();
379 jso2 = NULL;
380 r = ifapi_json_TPM2B_OPERAND_serialize(&in->operandB, &jso2);
381 return_if_error(r, "Serialize TPM2B_OPERAND");
382
383 json_object_object_add(*jso, "operandB", jso2);
384 if (in->offset != 0) {
385 jso2 = NULL;
386 r = ifapi_json_UINT16_serialize(in->offset, &jso2);
387 return_if_error(r, "Serialize UINT16");
388
389 json_object_object_add(*jso, "offset", jso2);
390 }
391 jso2 = NULL;
392 r = ifapi_json_TPM2_EO_serialize(in->operation, &jso2);
393 return_if_error(r, "Serialize TPM2_EO");
394
395 json_object_object_add(*jso, "operation", jso2);
396 return TSS2_RC_SUCCESS;
397 }
398
399 /** Serialize value of type TPMS_POLICYCOMMANDCODE to json.
400 *
401 * @param[in] in value to be serialized.
402 * @param[out] jso pointer to the json object.
403 * @retval TSS2_RC_SUCCESS if the function call was a success.
404 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
405 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYCOMMANDCODE.
406 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
407 */
408 TSS2_RC
409 ifapi_json_TPMS_POLICYCOMMANDCODE_serialize(const TPMS_POLICYCOMMANDCODE *in,
410 json_object **jso)
411 {
412 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
413
414 TSS2_RC r;
415 json_object *jso2;
416
417 if (*jso == NULL)
418 *jso = json_object_new_object();
419 jso2 = NULL;
420 r = ifapi_json_TPM2_CC_serialize(in->code, &jso2);
421 return_if_error(r, "Serialize TPM2_CC");
422
423 json_object_object_add(*jso, "code", jso2);
424 return TSS2_RC_SUCCESS;
425 }
426
427 /** Serialize value of type TPMS_POLICYPHYSICALPRESENCE to json.
428 *
429 * @param[in] in value to be serialized.
430 * @param[out] jso pointer to the json object.
431 * @retval TSS2_RC_SUCCESS if the function call was a success.
432 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
433 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYPHYSICALPRESENCE.
434 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
435 */
436 TSS2_RC
437 ifapi_json_TPMS_POLICYPHYSICALPRESENCE_serialize(const
438 TPMS_POLICYPHYSICALPRESENCE *in, json_object **jso)
439 {
440 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
441
442 if (*jso == NULL)
443 *jso = json_object_new_object();
444 return TSS2_RC_SUCCESS;
445 }
446
447 /** Serialize value of type TPMS_POLICYCPHASH to json.
448 *
449 * @param[in] in value to be serialized.
450 * @param[out] jso pointer to the json object.
451 * @retval TSS2_RC_SUCCESS if the function call was a success.
452 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
453 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYCPHASH.
454 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
455 */
456 TSS2_RC
457 ifapi_json_TPMS_POLICYCPHASH_serialize(const TPMS_POLICYCPHASH *in,
458 json_object **jso)
459 {
460 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
461
462 TSS2_RC r;
463 json_object *jso2;
464
465 if (*jso == NULL)
466 *jso = json_object_new_object();
467 jso2 = NULL;
468 r = ifapi_json_TPM2B_DIGEST_serialize(&in->cpHash, &jso2);
469 return_if_error(r, "Serialize TPM2B_DIGEST");
470
471 json_object_object_add(*jso, "cpHash", jso2);
472 return TSS2_RC_SUCCESS;
473 }
474
475 /** Serialize value of type TPMS_POLICYNAMEHASH to json.
476 *
477 * @param[in] in value to be serialized.
478 * @param[out] jso pointer to the json object.
479 * @retval TSS2_RC_SUCCESS if the function call was a success.
480 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
481 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYNAMEHASH.
482 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
483 */
484 TSS2_RC
485 ifapi_json_TPMS_POLICYNAMEHASH_serialize(const TPMS_POLICYNAMEHASH *in,
486 json_object **jso)
487 {
488 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
489
490 TSS2_RC r;
491 json_object *jso2, *jso_ary;
492 size_t i;
493 size_t cond_cnt = 0; /**< counter for conditional fields */
494
495 if (*jso == NULL) {
496 *jso = json_object_new_object();
497 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
498 }
499
500 if (in->nameHash.size) {
501 jso2 = NULL;
502 cond_cnt++;
503 r = ifapi_json_TPM2B_DIGEST_serialize(&in->nameHash, &jso2);
504 return_if_error(r, "Serialize TPM2B_DIGEST");
505
506 json_object_object_add(*jso, "nameHash", jso2);
507
508 /* No need to serialize namePaths or objectNames from which would be
509 needed to compute nameHash. */
510 return TSS2_RC_SUCCESS;
511 }
512
513 jso_ary = json_object_new_array();
514 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
515
516 if (in->namePaths[0]) {
517 /* Pathnamees for objects are used */
518 cond_cnt++;
519 for (i = 0; i < in->count; i++) {
520 jso2 = NULL;
521 r = ifapi_json_char_serialize(in->namePaths[i], &jso2);
522 return_if_error(r, "Serialize char");
523
524 json_object_array_add(jso_ary, jso2);
525 }
526 json_object_object_add(*jso, "namePaths", jso_ary);
527 } else {
528 /* TPM object names are used */
529 for (i = 0; i < in->count; i++) {
530 jso2 = NULL;
531 r = ifapi_json_TPM2B_NAME_serialize(&in->objectNames[i], &jso2);
532 return_if_error(r, "Serialize TPM2B_NAME");
533 json_object_array_add(jso_ary, jso2);
534 }
535 json_object_object_add(*jso, "objectNames", jso_ary);
536 }
537 /* Check whether only one condition field found in policy. */
538 if (cond_cnt != 1) {
539 return_error(TSS2_FAPI_RC_BAD_VALUE,
540 "Exactly one conditional is allowed for policy name hash.");
541 }
542
543 return TSS2_RC_SUCCESS;
544 }
545
546 /** Serialize value of type TPMS_POLICYDUPLICATIONSELECT to json.
547 *
548 * @param[in] in value to be serialized.
549 * @param[out] jso pointer to the json object.
550 * @retval TSS2_RC_SUCCESS if the function call was a success.
551 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
552 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYDUPLICATIONSELECT.
553 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
554 */
555 TSS2_RC
556 ifapi_json_TPMS_POLICYDUPLICATIONSELECT_serialize(const
557 TPMS_POLICYDUPLICATIONSELECT *in, json_object **jso)
558 {
559 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
560
561 TSS2_RC r;
562 json_object *jso2;
563 size_t cond_cnt = 0; /**< counter for conditional fields */
564
565 if (*jso == NULL)
566 *jso = json_object_new_object();
567 jso2 = NULL;
568 r = ifapi_json_TPM2B_NAME_serialize(&in->objectName, &jso2);
569 return_if_error(r, "Serialize TPM2B_NAME");
570
571 json_object_object_add(*jso, "objectName", jso2);
572
573 if (in->newParentName.size) {
574 cond_cnt++;
575 jso2 = NULL;
576 r = ifapi_json_TPM2B_NAME_serialize(&in->newParentName, &jso2);
577 return_if_error(r, "Serialize TPM2B_NAME");
578
579 json_object_object_add(*jso, "newParentName", jso2);
580 }
581 jso2 = NULL;
582 r = ifapi_json_TPMI_YES_NO_serialize(in->includeObject, &jso2);
583 return_if_error(r, "Serialize TPMI_YES_NO");
584
585 json_object_object_add(*jso, "includeObject", jso2);
586
587 if (in->newParentPath) {
588 jso2 = NULL;
589 cond_cnt++;
590 r = ifapi_json_char_serialize(in->newParentPath, &jso2);
591 return_if_error(r, "Serialize char");
592
593 json_object_object_add(*jso, "newParentPath", jso2);
594 }
595
596 if (in->newParentPublic.publicArea.type) {
597 jso2 = NULL;
598 r = ifapi_json_TPM2B_PUBLIC_serialize(&in->newParentPublic, &jso2);
599 return_if_error(r, "Serialize TPM2B_PUBLIC");
600
601 json_object_object_add(*jso, "newParentPublic", jso2);
602 }
603
604 /* Check whether only one condition field found in policy. */
605 if (cond_cnt != 1) {
606 return_error(TSS2_FAPI_RC_BAD_VALUE,
607 "Exactly one conditional is allowed for policy "
608 "duplication select.");
609 }
610 return TSS2_RC_SUCCESS;
611 }
612
613 /** Serialize value of type TPMS_POLICYAUTHORIZE to json.
614 *
615 * @param[in] in value to be serialized.
616 * @param[out] jso pointer to the json object.
617 * @retval TSS2_RC_SUCCESS if the function call was a success.
618 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
619 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYAUTHORIZE.
620 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
621 */
622 TSS2_RC
623 ifapi_json_TPMS_POLICYAUTHORIZE_serialize(const TPMS_POLICYAUTHORIZE *in,
624 json_object **jso)
625 {
626 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
627
628 TSS2_RC r;
629 json_object *jso2;
630 size_t cond_cnt = 0; /**< counter for conditional fields */
631
632 if (*jso == NULL)
633 *jso = json_object_new_object();
634 jso2 = NULL;
635 r = ifapi_json_TPM2B_DIGEST_serialize(&in->approvedPolicy, &jso2);
636 return_if_error(r, "Serialize TPM2B_DIGEST");
637
638 json_object_object_add(*jso, "approvedPolicy", jso2);
639 if (in->policyRef.size != 0) {
640 jso2 = NULL;
641 r = ifapi_json_TPM2B_NONCE_serialize(&in->policyRef, &jso2);
642 return_if_error(r, "Serialize TPM2B_NONCE");
643
644 json_object_object_add(*jso, "policyRef", jso2);
645 }
646 jso2 = NULL;
647 r = ifapi_json_TPM2B_NAME_serialize(&in->keyName, &jso2);
648 return_if_error(r, "Serialize TPM2B_NAME");
649
650 json_object_object_add(*jso, "keyName", jso2);
651 jso2 = NULL;
652 /*
653 r = ifapi_json_TPMT_TK_VERIFIED_serialize(&in->checkTicket, &jso2);
654 return_if_error(r, "Serialize TPMT_TK_VERIFIED");
655
656 json_object_object_add(*jso, "checkTicket", jso2);
657 jso2 = NULL;
658 */
659 if (in->keyPath) {
660 cond_cnt++;
661 r = ifapi_json_char_serialize(in->keyPath, &jso2);
662 return_if_error(r, "Serialize char");
663
664 json_object_object_add(*jso, "keyPath", jso2);
665 }
666 if (in->keyPublic.type != 0) {
667 jso2 = NULL;
668 cond_cnt++;
669 r = ifapi_json_TPMT_PUBLIC_serialize(&in->keyPublic, &jso2);
670 return_if_error(r, "Serialize TPMT_PUBLIC");
671
672 json_object_object_add(*jso, "keyPublic", jso2);
673 }
674 if ((in->keyPEM) && strcmp(in->keyPEM, "") != 0) {
675 jso2 = NULL;
676 r = ifapi_json_char_serialize(in->keyPEM, &jso2);
677 return_if_error(r, "Serialize char");
678
679 json_object_object_add(*jso, "keyPEM", jso2);
680 }
681 if (in->keyPEMhashAlg != 0) {
682 jso2 = NULL;
683 r = ifapi_json_TPMI_ALG_HASH_serialize(in->keyPEMhashAlg, &jso2);
684 return_if_error(r, "Serialize TPMI_ALG_HASH");
685
686 json_object_object_add(*jso, "keyPEMhashAlg", jso2);
687 }
688
689 return TSS2_RC_SUCCESS;
690 }
691
692 /** Serialize value of type TPMS_POLICYAUTHVALUE to json.
693 *
694 * @param[in] in value to be serialized.
695 * @param[out] jso pointer to the json object.
696 * @retval TSS2_RC_SUCCESS if the function call was a success.
697 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
698 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYAUTHVALUE.
699 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
700 */
701 TSS2_RC
702 ifapi_json_TPMS_POLICYAUTHVALUE_serialize(const TPMS_POLICYAUTHVALUE *in,
703 json_object **jso)
704 {
705 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
706
707 if (*jso == NULL)
708 *jso = json_object_new_object();
709 return TSS2_RC_SUCCESS;
710 }
711
712 /** Serialize value of type TPMS_POLICYPASSWORD to json.
713 *
714 * @param[in] in value to be serialized.
715 * @param[out] jso pointer to the json object.
716 * @retval TSS2_RC_SUCCESS if the function call was a success.
717 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
718 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYPASSWORD.
719 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
720 */
721 TSS2_RC
722 ifapi_json_TPMS_POLICYPASSWORD_serialize(const TPMS_POLICYPASSWORD *in,
723 json_object **jso)
724 {
725 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
726
727 if (*jso == NULL)
728 *jso = json_object_new_object();
729 return TSS2_RC_SUCCESS;
730 }
731
732 /** Serialize value of type TPMS_POLICYNVWRITTEN to json.
733 *
734 * @param[in] in value to be serialized.
735 * @param[out] jso pointer to the json object.
736 * @retval TSS2_RC_SUCCESS if the function call was a success.
737 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
738 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYNVWRITTEN.
739 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
740 */
741 TSS2_RC
742 ifapi_json_TPMS_POLICYNVWRITTEN_serialize(const TPMS_POLICYNVWRITTEN *in,
743 json_object **jso)
744 {
745 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
746
747 TSS2_RC r;
748 json_object *jso2;
749
750 if (*jso == NULL)
751 *jso = json_object_new_object();
752 jso2 = NULL;
753 r = ifapi_json_TPMI_YES_NO_serialize(in->writtenSet, &jso2);
754 return_if_error(r, "Serialize TPMI_YES_NO");
755
756 json_object_object_add(*jso, "writtenSet", jso2);
757 return TSS2_RC_SUCCESS;
758 }
759
760 /** Serialize value of type TPMS_POLICYTEMPLATE to json.
761 *
762 * @param[in] in value to be serialized.
763 * @param[out] jso pointer to the json object.
764 * @retval TSS2_RC_SUCCESS if the function call was a success.
765 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
766 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYTEMPLATE.
767 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
768 */
769 TSS2_RC
770 ifapi_json_TPMS_POLICYTEMPLATE_serialize(const TPMS_POLICYTEMPLATE *in,
771 json_object **jso)
772 {
773 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
774
775 TSS2_RC r;
776 json_object *jso2;
777 size_t cond_cnt = 0; /**< counter for conditional fields */
778
779 if (*jso == NULL)
780 *jso = json_object_new_object();
781 if (in->templateHash.size != 0) {
782 jso2 = NULL;
783 cond_cnt++;
784 r = ifapi_json_TPM2B_DIGEST_serialize(&in->templateHash, &jso2);
785 return_if_error(r, "Serialize TPM2B_DIGEST");
786
787 json_object_object_add(*jso, "templateHash", jso2);
788 }
789 if (in->templatePublic.size != 0) {
790 jso2 = NULL;
791 cond_cnt++;
792 r = ifapi_json_TPM2B_PUBLIC_serialize(&in->templatePublic, &jso2);
793 return_if_error(r, "Serialize TPM2B_PUBLIC");
794
795 json_object_object_add(*jso, "templatePublic", jso2);
796 }
797 if (in->templateName) {
798 jso2 = NULL;
799 cond_cnt++;
800 r = ifapi_json_char_serialize(in->templateName, &jso2);
801 return_if_error(r, "Serialize char");
802
803 json_object_object_add(*jso, "templateName", jso2);
804 }
805
806 /* Check whether only one condition field found in policy. */
807 if (cond_cnt != 1) {
808 return_error(TSS2_FAPI_RC_BAD_VALUE,
809 "Exactly one conditional is allowed for policy template.");
810 }
811 return TSS2_RC_SUCCESS;
812 }
813
814 /** Serialize value of type TPMS_POLICYAUTHORIZENV to json.
815 *
816 * @param[in] in value to be serialized.
817 * @param[out] jso pointer to the json object.
818 * @retval TSS2_RC_SUCCESS if the function call was a success.
819 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
820 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYAUTHORIZENV.
821 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
822 */
823 TSS2_RC
824 ifapi_json_TPMS_POLICYAUTHORIZENV_serialize(const TPMS_POLICYAUTHORIZENV *in,
825 json_object **jso)
826 {
827 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
828
829 TSS2_RC r;
830 json_object *jso2;
831 size_t cond_cnt = 0; /**< counter for conditional fields */
832
833 if (*jso == NULL)
834 *jso = json_object_new_object();
835 jso2 = NULL;
836 if (in->nvPath) {
837 cond_cnt++;
838 r = ifapi_json_char_serialize(in->nvPath, &jso2);
839 return_if_error(r, "Serialize char");
840
841 json_object_object_add(*jso, "nvPath", jso2);
842 }
843 jso2 = NULL;
844 if (in->nvPublic.nvPublic.nvIndex > 0) {
845 cond_cnt++;
846 /* Template already instantiated */
847 r = ifapi_json_TPM2B_NV_PUBLIC_serialize(&in->nvPublic, &jso2);
848 return_if_error(r, "Serialize TPM2B_NV_PUBLIC");
849
850 json_object_object_add(*jso, "nvPublic", jso2);
851 }
852 if (cond_cnt != 1) {
853 return_error(TSS2_FAPI_RC_BAD_VALUE,
854 "Exactly one conditional needed for policy authorize nv .");
855 }
856 return TSS2_RC_SUCCESS;
857 }
858
859 /** Serialize value of type TPMS_POLICYACTION to json.
860 *
861 * @param[in] in value to be serialized.
862 * @param[out] jso pointer to the json object.
863 * @retval TSS2_RC_SUCCESS if the function call was a success.
864 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
865 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYACTION.
866 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
867 */
868 TSS2_RC
869 ifapi_json_TPMS_POLICYACTION_serialize(const TPMS_POLICYACTION *in,
870 json_object **jso)
871 {
872 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
873
874 TSS2_RC r;
875 json_object *jso2;
876
877 if (*jso == NULL)
878 *jso = json_object_new_object();
879 jso2 = NULL;
880 r = ifapi_json_char_serialize(in->action, &jso2);
881 return_if_error(r, "Serialize char");
882
883 json_object_object_add(*jso, "action", jso2);
884 return TSS2_RC_SUCCESS;
885 }
886
887 /** Serialize value of type TPMS_PCRVALUE to json.
888 *
889 * @param[in] in value to be serialized.
890 * @param[out] jso pointer to the json object.
891 * @retval TSS2_RC_SUCCESS if the function call was a success.
892 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
893 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_PCRVALUE.
894 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
895 */
896 TSS2_RC
897 ifapi_json_TPMS_PCRVALUE_serialize(const TPMS_PCRVALUE *in, json_object **jso)
898 {
899 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
900
901 TSS2_RC r;
902 json_object *jso2;
903
904 if (*jso == NULL)
905 *jso = json_object_new_object();
906 jso2 = NULL;
907 r = ifapi_json_UINT32_serialize(in->pcr, &jso2);
908 return_if_error(r, "Serialize UINT32");
909
910 json_object_object_add(*jso, "pcr", jso2);
911 jso2 = NULL;
912 r = ifapi_json_TPM2_ALG_ID_serialize(in->hashAlg, &jso2);
913 return_if_error(r, "Serialize TPM2_ALG_ID");
914
915 json_object_object_add(*jso, "hashAlg", jso2);
916 jso2 = NULL;
917 r = ifapi_json_TPMU_HA_serialize(&in->digest, in->hashAlg, &jso2);
918 return_if_error(r, "Serialize TPMU_HA");
919
920 json_object_object_add(*jso, "digest", jso2);
921 return TSS2_RC_SUCCESS;
922 }
923
924 /** Serialize value of type TPML_PCRVALUES to json.
925 *
926 * @param[in] in value to be serialized.
927 * @param[out] jso pointer to the json object.
928 * @retval TSS2_RC_SUCCESS if the function call was a success.
929 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
930 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_PCRVALUES.
931 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
932 */
933 TSS2_RC
934 ifapi_json_TPML_PCRVALUES_serialize(const TPML_PCRVALUES *in, json_object **jso)
935 {
936 TSS2_RC r;
937 json_object *jso2;
938
939 if (*jso == NULL)
940 *jso = json_object_new_array();
941 jso2 = NULL;
942 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
943
944 for (size_t i = 0; i < in->count; i++) {
945 jso2 = NULL;
946 r = ifapi_json_TPMS_PCRVALUE_serialize(&in->pcrs[i], &jso2);
947 return_if_error(r, "Serialize TPMS_PCRVALUE");
948
949 json_object_array_add(*jso, jso2);
950 }
951 return TSS2_RC_SUCCESS;
952 }
953
954 /** Serialize value of type TPMS_POLICYPCR to json.
955 *
956 * @param[in] in value to be serialized.
957 * @param[out] jso pointer to the json object.
958 * @retval TSS2_RC_SUCCESS if the function call was a success.
959 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
960 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYPCR.
961 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
962 */
963 TSS2_RC
964 ifapi_json_TPMS_POLICYPCR_serialize(const TPMS_POLICYPCR *in, json_object **jso)
965 {
966 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
967
968 TSS2_RC r;
969 json_object *jso2;
970 size_t cond_cnt = 0; /**< counter for conditional fields */
971
972 if (in->pcrs) {
973 if (*jso == NULL)
974 *jso = json_object_new_object();
975 jso2 = NULL;
976 cond_cnt++;
977 r = ifapi_json_TPML_PCRVALUES_serialize(in->pcrs, &jso2);
978 return_if_error(r, "Serialize TPML_PCRVALUES");
979
980 json_object_object_add(*jso, "pcrs", jso2);
981 }
982
983 if (in->currentPCRandBanks.count) {
984 jso2 = NULL;
985 cond_cnt++;
986 r = ifapi_json_TPML_PCR_SELECTION_serialize(&in->currentPCRandBanks, &jso2);
987 return_if_error(r, "Serialize TPML_PCR_SELECTION");
988
989 json_object_object_add(*jso, "currentPCRandBanks", jso2);
990 }
991
992 if (in->currentPCRs.sizeofSelect) {
993 jso2 = NULL;
994 cond_cnt++;
995 r = ifapi_json_TPMS_PCR_SELECT_serialize(&in->currentPCRs, &jso2);
996 return_if_error(r, "Serialize TPMS_PCR_SELECT");
997
998 json_object_object_add(*jso, "currentPCRs", jso2);
999 }
1000 /* Check whether only one conditional is used. */
1001 if (cond_cnt != 1) {
1002 return_error(TSS2_FAPI_RC_BAD_VALUE,
1003 "Exactly one conditional is allowed for policy pcr.");
1004 }
1005 return TSS2_RC_SUCCESS;
1006 }
1007
1008 /** Serialize value of type TPMS_POLICYAUTHORIZATION to json.
1009 *
1010 * @param[in] in value to be serialized.
1011 * @param[out] jso pointer to the json object.
1012 * @retval TSS2_RC_SUCCESS if the function call was a success.
1013 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1014 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYAUTHORIZATION.
1015 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1016 */
1017 TSS2_RC
1018 ifapi_json_TPMS_POLICYAUTHORIZATION_serialize(
1019 const TPMS_POLICYAUTHORIZATION *in,
1020 json_object **jso)
1021 {
1022 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1023
1024 TSS2_RC r;
1025 json_object *jso2;
1026
1027 if (*jso == NULL)
1028 *jso = json_object_new_object();
1029 jso2 = NULL;
1030 r = ifapi_json_char_serialize(in->type, &jso2);
1031 return_if_error(r, "Serialize char");
1032
1033 json_object_object_add(*jso, "type", jso2);
1034 jso2 = NULL;
1035 r = ifapi_json_TPMT_PUBLIC_serialize(&in->key, &jso2);
1036 return_if_error(r, "Serialize TPMT_PUBLIC");
1037
1038 json_object_object_add(*jso, "key", jso2);
1039 jso2 = NULL;
1040 r = ifapi_json_TPM2B_NONCE_serialize(&in->policyRef, &jso2);
1041 return_if_error(r, "Serialize TPM2B_NONCE");
1042
1043 json_object_object_add(*jso, "policyRef", jso2);
1044 jso2 = NULL;
1045 r = ifapi_json_TPMT_SIGNATURE_serialize(&in->signature, &jso2);
1046 return_if_error(r, "Serialize TPMT_SIGNATURE");
1047
1048 json_object_object_add(*jso, "signature", jso2);
1049 return TSS2_RC_SUCCESS;
1050 }
1051
1052 /** Serialize value of type TPML_POLICYAUTHORIZATIONS to json.
1053 *
1054 * @param[in] in value to be serialized.
1055 * @param[out] jso pointer to the json object.
1056 * @retval TSS2_RC_SUCCESS if the function call was a success.
1057 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1058 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_POLICYAUTHORIZATIONS.
1059 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1060 */
1061 TSS2_RC
1062 ifapi_json_TPML_POLICYAUTHORIZATIONS_serialize(const TPML_POLICYAUTHORIZATIONS
1063 *in, json_object **jso)
1064 {
1065 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1066
1067 TSS2_RC r;
1068 json_object *jso2;
1069
1070 if (*jso == NULL)
1071 *jso = json_object_new_array();
1072 jso2 = NULL;
1073 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1074 jso2 = NULL;
1075 for (size_t i = 0; i < in->count; i++) {
1076 jso2 = NULL;
1077 r = ifapi_json_TPMS_POLICYAUTHORIZATION_serialize(&in->authorizations[i],
1078 &jso2);
1079 return_if_error(r, "Serialize TPMS_POLICYAUTHORIZATION");
1080
1081 json_object_array_add(*jso, jso2);
1082 }
1083 return TSS2_RC_SUCCESS;
1084 }
1085
1086 /** Serialize value of type TPMS_POLICYBRANCH to json.
1087 *
1088 * @param[in] in value to be serialized.
1089 * @param[out] jso pointer to the json object.
1090 * @retval TSS2_RC_SUCCESS if the function call was a success.
1091 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1092 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYBRANCH.
1093 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1094 */
1095 TSS2_RC
1096 ifapi_json_TPMS_POLICYBRANCH_serialize(const TPMS_POLICYBRANCH *in,
1097 json_object **jso)
1098 {
1099 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1100
1101 TSS2_RC r;
1102 json_object *jso2;
1103
1104 if (*jso == NULL)
1105 *jso = json_object_new_object();
1106 jso2 = NULL;
1107 r = ifapi_json_char_serialize(in->name, &jso2);
1108 return_if_error(r, "Serialize char");
1109
1110 json_object_object_add(*jso, "name", jso2);
1111 jso2 = NULL;
1112 r = ifapi_json_char_serialize(in->description, &jso2);
1113 return_if_error(r, "Serialize char");
1114
1115 json_object_object_add(*jso, "description", jso2);
1116 jso2 = NULL;
1117 r = ifapi_json_TPML_POLICYELEMENTS_serialize(in->policy, &jso2);
1118 return_if_error(r, "Serialize TPML_POLICYELEMENTS");
1119
1120 json_object_object_add(*jso, "policy", jso2);
1121 if (in->policyDigests.count > 0) {
1122 jso2 = NULL;
1123 r = ifapi_json_TPML_DIGEST_VALUES_serialize(&in->policyDigests, &jso2);
1124 return_if_error(r, "Serialize TPML_DIGEST_VALUES");
1125
1126 json_object_object_add(*jso, "policyDigests", jso2);
1127 }
1128 return TSS2_RC_SUCCESS;
1129 }
1130
1131 /** Serialize value of type TPML_POLICYBRANCHES to json.
1132 *
1133 * @param[in] in value to be serialized.
1134 * @param[out] jso pointer to the json object.
1135 * @retval TSS2_RC_SUCCESS if the function call was a success.
1136 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1137 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_POLICYBRANCHES.
1138 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1139 */
1140 TSS2_RC
1141 ifapi_json_TPML_POLICYBRANCHES_serialize(const TPML_POLICYBRANCHES *in,
1142 json_object **jso)
1143 {
1144 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1145
1146 TSS2_RC r;
1147 json_object *jso2;
1148
1149 if (*jso == NULL)
1150 *jso = json_object_new_array();
1151 jso2 = NULL;
1152 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1153 jso2 = NULL;
1154 for (size_t i = 0; i < in->count; i++) {
1155 jso2 = NULL;
1156 r = ifapi_json_TPMS_POLICYBRANCH_serialize(&in->authorizations[i], &jso2);
1157 return_if_error(r, "Serialize TPMS_POLICYBRANCH");
1158
1159 json_object_array_add(*jso, jso2);
1160 }
1161 return TSS2_RC_SUCCESS;
1162 }
1163
1164 /** Serialize value of type TPMS_POLICYOR to json.
1165 *
1166 * @param[in] in value to be serialized.
1167 * @param[out] jso pointer to the json object.
1168 * @retval TSS2_RC_SUCCESS if the function call was a success.
1169 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1170 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICYOR.
1171 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1172 */
1173 TSS2_RC
1174 ifapi_json_TPMS_POLICYOR_serialize(const TPMS_POLICYOR *in, json_object **jso)
1175 {
1176 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1177
1178 TSS2_RC r;
1179 json_object *jso2;
1180
1181 if (*jso == NULL)
1182 *jso = json_object_new_object();
1183 jso2 = NULL;
1184 r = ifapi_json_TPML_POLICYBRANCHES_serialize(in->branches, &jso2);
1185 return_if_error(r, "Serialize TPML_POLICYBRANCHES");
1186
1187 json_object_object_add(*jso, "branches", jso2);
1188 return TSS2_RC_SUCCESS;
1189 }
1190
1191 /** Serialize a TPMU_POLICYELEMENT to json.
1192 *
1193 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
1194 * @param[in] in the value to be serialized.
1195 * @param[in] selector the type of the policy element.
1196 * @param[out] jso pointer to the json object.
1197 * @retval TSS2_RC_SUCCESS if the function call was a success.
1198 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1199 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_POLICYELEMENT.
1200 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1201 */
1202 TSS2_RC
1203 ifapi_json_TPMU_POLICYELEMENT_serialize(const TPMU_POLICYELEMENT *in,
1204 UINT32 selector, json_object **jso)
1205 {
1206 if (*jso == NULL)
1207 *jso = json_object_new_object();
1208 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1209
1210 switch (selector) {
1211 case POLICYOR:
1212 return ifapi_json_TPMS_POLICYOR_serialize(&in->PolicyOr, jso);
1213 case POLICYSIGNED:
1214 return ifapi_json_TPMS_POLICYSIGNED_serialize(&in->PolicySigned, jso);
1215 case POLICYSECRET:
1216 return ifapi_json_TPMS_POLICYSECRET_serialize(&in->PolicySecret, jso);
1217 case POLICYPCR:
1218 return ifapi_json_TPMS_POLICYPCR_serialize(&in->PolicyPCR, jso);
1219 case POLICYLOCALITY:
1220 return ifapi_json_TPMS_POLICYLOCALITY_serialize(&in->PolicyLocality, jso);
1221 case POLICYNV:
1222 return ifapi_json_TPMS_POLICYNV_serialize(&in->PolicyNV, jso);
1223 case POLICYCOUNTERTIMER:
1224 return ifapi_json_TPMS_POLICYCOUNTERTIMER_serialize(&in->PolicyCounterTimer,
1225 jso);
1226 case POLICYCOMMANDCODE:
1227 return ifapi_json_TPMS_POLICYCOMMANDCODE_serialize(&in->PolicyCommandCode, jso);
1228 case POLICYPHYSICALPRESENCE:
1229 return ifapi_json_TPMS_POLICYPHYSICALPRESENCE_serialize(
1230 &in->PolicyPhysicalPresence, jso);
1231 case POLICYCPHASH:
1232 return ifapi_json_TPMS_POLICYCPHASH_serialize(&in->PolicyCpHash, jso);
1233 case POLICYNAMEHASH:
1234 return ifapi_json_TPMS_POLICYNAMEHASH_serialize(&in->PolicyNameHash, jso);
1235 case POLICYDUPLICATIONSELECT:
1236 return ifapi_json_TPMS_POLICYDUPLICATIONSELECT_serialize(
1237 &in->PolicyDuplicationSelect, jso);
1238 case POLICYAUTHORIZE:
1239 return ifapi_json_TPMS_POLICYAUTHORIZE_serialize(&in->PolicyAuthorize, jso);
1240 case POLICYAUTHVALUE:
1241 return ifapi_json_TPMS_POLICYAUTHVALUE_serialize(&in->PolicyAuthValue, jso);
1242 case POLICYPASSWORD:
1243 return ifapi_json_TPMS_POLICYPASSWORD_serialize(&in->PolicyPassword, jso);
1244 case POLICYNVWRITTEN:
1245 return ifapi_json_TPMS_POLICYNVWRITTEN_serialize(&in->PolicyNvWritten, jso);
1246 case POLICYTEMPLATE:
1247 return ifapi_json_TPMS_POLICYTEMPLATE_serialize(&in->PolicyTemplate, jso);
1248 case POLICYAUTHORIZENV:
1249 return ifapi_json_TPMS_POLICYAUTHORIZENV_serialize(&in->PolicyAuthorizeNv, jso);
1250 case POLICYACTION:
1251 return ifapi_json_TPMS_POLICYACTION_serialize(&in->PolicyAction, jso);
1252 default:
1253 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
1254 return TSS2_SYS_RC_BAD_VALUE;
1255 };
1256 return TSS2_RC_SUCCESS;
1257 }
1258
1259 /** Serialize value of type TPMT_POLICYELEMENT to json.
1260 *
1261 * @param[in] in value to be serialized.
1262 * @param[out] jso pointer to the json object.
1263 * @retval TSS2_RC_SUCCESS if the function call was a success.
1264 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1265 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_POLICYELEMENT.
1266 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1267 */
1268 TSS2_RC
1269 ifapi_json_TPMT_POLICYELEMENT_serialize(const TPMT_POLICYELEMENT *in,
1270 json_object **jso)
1271 {
1272 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1273
1274 TSS2_RC r;
1275 json_object *jso2;
1276
1277 if (*jso == NULL)
1278 *jso = json_object_new_object();
1279 jso2 = NULL;
1280 r = ifapi_json_TPMI_POLICYTYPE_serialize(in->type, &jso2);
1281 return_if_error(r, "Serialize TPMI_POLICYTYPE");
1282
1283 json_object_object_add(*jso, "type", jso2);
1284
1285 if (in->policyDigests.count > 0) {
1286 jso2 = NULL;
1287 r = ifapi_json_TPML_DIGEST_VALUES_serialize(&in->policyDigests, &jso2);
1288 return_if_error(r, "Serialize TPML_DIGEST_VALUES");
1289
1290 json_object_object_add(*jso, "policyDigests", jso2);
1291 }
1292 r = ifapi_json_TPMU_POLICYELEMENT_serialize(&in->element, in->type, jso);
1293 return_if_error(r, "Serialize TPMU_POLICYELEMENT");
1294
1295 return TSS2_RC_SUCCESS;
1296 }
1297
1298 /** Serialize value of type TPML_POLICYELEMENTS to json.
1299 *
1300 * @param[in] in value to be serialized.
1301 * @param[out] jso pointer to the json object.
1302 * @retval TSS2_RC_SUCCESS if the function call was a success.
1303 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1304 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_POLICYELEMENTS.
1305 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1306 */
1307 TSS2_RC
1308 ifapi_json_TPML_POLICYELEMENTS_serialize(const TPML_POLICYELEMENTS *in,
1309 json_object **jso)
1310 {
1311 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1312
1313 TSS2_RC r;
1314 json_object *jso2;
1315
1316 if (*jso == NULL)
1317 *jso = json_object_new_array();
1318 jso2 = NULL;
1319 return_if_null(jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1320
1321 for (size_t i = 0; i < in->count; i++) {
1322 jso2 = NULL;
1323 r = ifapi_json_TPMT_POLICYELEMENT_serialize(&in->elements[i], &jso2);
1324 return_if_error(r, "Serialize TPMT_POLICYELEMENT");
1325
1326 json_object_array_add(*jso, jso2);
1327 }
1328 return TSS2_RC_SUCCESS;
1329 }
1330
1331 /** Serialize value of type TPMS_POLICY to json.
1332 *
1333 * @param[in] in value to be serialized.
1334 * @param[out] jso pointer to the json object.
1335 * @retval TSS2_RC_SUCCESS if the function call was a success.
1336 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1337 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_POLICY.
1338 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1339 */
1340 TSS2_RC
1341 ifapi_json_TPMS_POLICY_serialize(const TPMS_POLICY *in,
1342 json_object **jso)
1343 {
1344 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1345
1346 TSS2_RC r;
1347 json_object *jso2;
1348
1349 if (*jso == NULL)
1350 *jso = json_object_new_object();
1351 jso2 = NULL;
1352 r = ifapi_json_char_serialize(in->description, &jso2);
1353 return_if_error(r, "Serialize char");
1354
1355 json_object_object_add(*jso, "description", jso2);
1356 jso2 = NULL;
1357 r = ifapi_json_TPML_DIGEST_VALUES_serialize(&in->policyDigests, &jso2);
1358 return_if_error(r, "Serialize TPML_DIGEST_VALUES");
1359
1360 json_object_object_add(*jso, "policyDigests", jso2);
1361 if (in->policyAuthorizations) {
1362 jso2 = NULL;
1363 r = ifapi_json_TPML_POLICYAUTHORIZATIONS_serialize(in->policyAuthorizations,
1364 &jso2);
1365 return_if_error(r, "Serialize TPML_POLICYAUTHORIZATIONS");
1366
1367 json_object_object_add(*jso, "policyAuthorizations", jso2);
1368 }
1369 jso2 = NULL;
1370 r = ifapi_json_TPML_POLICYELEMENTS_serialize(in->policy, &jso2);
1371 return_if_error(r, "Serialize TPML_POLICYELEMENTS");
1372
1373 json_object_object_add(*jso, "policy", jso2);
1374 return TSS2_RC_SUCCESS;
1375 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef IFAPI_POLICY_JSON_SERIALIZE_H
6 #define IFAPI_POLICY_JSON_SERIALIZE_H
7
8 #include <stdbool.h>
9 #include <json-c/json.h>
10 #include <json-c/json_util.h>
11
12 #include "tss2_tpm2_types.h"
13 #include "fapi_int.h"
14
15 TSS2_RC
16 ifapi_json_TPMI_POLICYTYPE_serialize(const TPMI_POLICYTYPE in,
17 json_object **jso);
18
19 TSS2_RC
20 ifapi_json_TPMI_POLICYTYPE_serialize_txt(const TPMI_POLICYTYPE in,
21 json_object **jso);
22
23 TSS2_RC
24 ifapi_json_TPMS_POLICYSIGNED_serialize(const TPMS_POLICYSIGNED *in,
25 json_object **jso);
26
27 TSS2_RC
28 ifapi_json_TPMS_POLICYSECRET_serialize(const TPMS_POLICYSECRET *in,
29 json_object **jso);
30
31 TSS2_RC
32 ifapi_json_TPMS_POLICYLOCALITY_serialize(const TPMS_POLICYLOCALITY *in,
33 json_object **jso);
34
35 TSS2_RC
36 ifapi_json_TPMS_POLICYNV_serialize(const TPMS_POLICYNV *in, json_object **jso);
37
38 TSS2_RC
39 ifapi_json_TPMS_POLICYCOUNTERTIMER_serialize(const TPMS_POLICYCOUNTERTIMER *in,
40 json_object **jso);
41
42 TSS2_RC
43 ifapi_json_TPMS_POLICYCOMMANDCODE_serialize(const TPMS_POLICYCOMMANDCODE *in,
44 json_object **jso);
45
46 TSS2_RC
47 ifapi_json_TPMS_POLICYPHYSICALPRESENCE_serialize(const
48 TPMS_POLICYPHYSICALPRESENCE *in, json_object **jso);
49
50 TSS2_RC
51 ifapi_json_TPMS_POLICYCPHASH_serialize(const TPMS_POLICYCPHASH *in,
52 json_object **jso);
53
54 TSS2_RC
55 ifapi_json_TPMS_POLICYNAMEHASH_serialize(const TPMS_POLICYNAMEHASH *in,
56 json_object **jso);
57
58 TSS2_RC
59 ifapi_json_TPMS_POLICYDUPLICATIONSELECT_serialize(const
60 TPMS_POLICYDUPLICATIONSELECT *in, json_object **jso);
61
62 TSS2_RC
63 ifapi_json_TPMS_POLICYAUTHORIZE_serialize(const TPMS_POLICYAUTHORIZE *in,
64 json_object **jso);
65
66 TSS2_RC
67 ifapi_json_TPMS_POLICYAUTHVALUE_serialize(const TPMS_POLICYAUTHVALUE *in,
68 json_object **jso);
69
70 TSS2_RC
71 ifapi_json_TPMS_POLICYPASSWORD_serialize(const TPMS_POLICYPASSWORD *in,
72 json_object **jso);
73
74 TSS2_RC
75 ifapi_json_TPMS_POLICYNVWRITTEN_serialize(const TPMS_POLICYNVWRITTEN *in,
76 json_object **jso);
77
78 TSS2_RC
79 ifapi_json_TPMS_POLICYTEMPLATE_serialize(const TPMS_POLICYTEMPLATE *in,
80 json_object **jso);
81
82 TSS2_RC
83 ifapi_json_TPMS_POLICYAUTHORIZENV_serialize(const TPMS_POLICYAUTHORIZENV *in,
84 json_object **jso);
85
86 TSS2_RC
87 ifapi_json_TPMS_POLICYACTION_serialize(const TPMS_POLICYACTION *in,
88 json_object **jso);
89
90 TSS2_RC
91 ifapi_json_TPMS_PCRVALUE_serialize(const TPMS_PCRVALUE *in, json_object **jso);
92
93 TSS2_RC
94 ifapi_json_TPML_PCRVALUES_serialize(const TPML_PCRVALUES *in,
95 json_object **jso);
96
97 TSS2_RC
98 ifapi_json_TPMS_POLICYPCR_serialize(const TPMS_POLICYPCR *in,
99 json_object **jso);
100
101 TSS2_RC
102 ifapi_json_TPMS_POLICYAUTHORIZATION_serialize(const TPMS_POLICYAUTHORIZATION
103 *in, json_object **jso);
104
105 TSS2_RC
106 ifapi_json_TPML_POLICYAUTHORIZATIONS_serialize(const TPML_POLICYAUTHORIZATIONS
107 *in, json_object **jso);
108
109 TSS2_RC
110 ifapi_json_TPMS_POLICYBRANCH_serialize(const TPMS_POLICYBRANCH *in,
111 json_object **jso);
112
113 TSS2_RC
114 ifapi_json_TPML_POLICYBRANCHES_serialize(const TPML_POLICYBRANCHES *in,
115 json_object **jso);
116
117 TSS2_RC
118 ifapi_json_TPMS_POLICYOR_serialize(const TPMS_POLICYOR *in, json_object **jso);
119
120 TSS2_RC
121 ifapi_json_TPMU_POLICYELEMENT_serialize(const TPMU_POLICYELEMENT *in,
122 UINT32 selector, json_object **jso);
123
124 TSS2_RC
125 ifapi_json_TPMT_POLICYELEMENT_serialize(const TPMT_POLICYELEMENT *in,
126 json_object **jso);
127
128 TSS2_RC
129 ifapi_json_TPML_POLICYELEMENTS_serialize(const TPML_POLICYELEMENTS *in,
130 json_object **jso);
131
132 TSS2_RC
133 ifapi_json_TPMS_POLICY_serialize(const TPMS_POLICY *in,
134 json_object **jso);
135
136 #endif /* IFAPI_POLICY_JSON_SERIALIZE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #include <dirent.h>
9 #endif
10
11 #include "ifapi_io.h"
12 #include "ifapi_helpers.h"
13 #include "ifapi_policy_types.h"
14 #include "ifapi_policy_store.h"
15 #include "ifapi_macros.h"
16 #define LOGMODULE fapi
17 #include "util/log.h"
18 #include "util/aux_util.h"
19 #include "ifapi_policy_json_deserialize.h"
20 #include "ifapi_policy_json_serialize.h"
21
22 /** Compute absolute path of policy for IO.
23 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
24 */
25 static TSS2_RC
26 policy_rel_path_to_abs_path(
27 IFAPI_POLICY_STORE *pstore,
28 const char *rel_path,
29 char **abs_path)
30 {
31 TSS2_RC r;
32
33 if (ifapi_path_type_p(rel_path, IFAPI_POLICY_PATH)) {
34 r = ifapi_asprintf(abs_path, "%s%s%s.json", pstore->policydir,
35 IFAPI_FILE_DELIM, rel_path);
36 } else {
37 r = ifapi_asprintf(abs_path, "%s%s%s%s%s.json", pstore->policydir,
38 IFAPI_FILE_DELIM, IFAPI_POLICY_PATH, IFAPI_FILE_DELIM, rel_path);
39
40 }
41 return_if_error(r, "Create policy file name.");
42 return r;
43 }
44 /** Remove file storing a policy object.
45 *
46 * @param[in] pstore The policy directory.
47 * @param[in] path The relative name of the object be removed.
48 * @retval TSS2_RC_SUCCESS On success.
49 * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated.
50 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If no file is found in policy store.
51 * @retval TSS2_FAPI_RC_IO_ERROR If the file can't be removed.
52 */
53 TSS2_RC
54 ifapi_policy_delete(
55 IFAPI_POLICY_STORE * pstore,
56 char *path)
57 {
58 TSS2_RC r;
59 char *abs_path = NULL;
60
61 /* Convert relative path to absolute path in policy store */
62 r = policy_rel_path_to_abs_path(pstore, path, &abs_path);
63 goto_if_error2(r, "Path %s could not be created.", cleanup, path);
64
65 if (!ifapi_io_path_exists(abs_path)) {
66 goto_error(r, TSS2_FAPI_RC_PATH_NOT_FOUND,
67 "Policy %s not found.", cleanup, path);
68 }
69
70 if (remove(abs_path) != 0) {
71 LOG_WARNING("File: %s can't be deleted.", abs_path);
72 }
73
74 cleanup:
75 SAFE_FREE(abs_path);
76 return r;
77 }
78
79 /** Store policy store parameters in the policy store context.
80 *
81 * Also the user directory will be created if it does not exist.
82 *
83 * @param[out] pstore The keystore to be initialized.
84 * @param[in] config_policydir The configured policy directory.
85 * @retval TSS2_RC_SUCCESS If the keystore can be initialized.
86 * @retval TSS2_FAPI_RC_IO_ERROR If the policy store can't be
87 * initialized.
88 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
89 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
90 * the function.
91 */
92 TSS2_RC
93 ifapi_policy_store_initialize(
94 IFAPI_POLICY_STORE *pstore,
95 const char *config_policydir)
96 {
97 TSS2_RC r;
98 char *policy_dir = NULL;
99
100 memset(pstore, 0, sizeof(IFAPI_POLICY_STORE));
101 strdup_check(pstore->policydir, config_policydir, r, error);
102
103 r = ifapi_asprintf(&policy_dir, "%s%s%s", config_policydir, IFAPI_FILE_DELIM,
104 IFAPI_POLICY_PATH);
105 goto_if_error(r, "Out of memory.", error);
106
107 r = ifapi_io_check_create_dir(policy_dir);
108 goto_if_error2(r, "Policy directory %s can't be created.", error, policy_dir);
109
110 SAFE_FREE(policy_dir);
111 return TSS2_RC_SUCCESS;
112
113 error:
114 SAFE_FREE(policy_dir);
115 return r;
116 }
117
118 /** Start loading FAPI policy from policy store.
119 *
120 * Keys objects, NV objects, and hierarchies can be loaded.
121 *
122 * @param[in] pstore The policy directory.
123 * @param[in] io The input/output context being used for file I/O.
124 * @param[in] path The relative path of the object. For keys the path will
125 * expanded if possible.
126 * @retval TSS2_RC_SUCCESS If the object can be read.
127 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered.
128 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist.
129 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
130 */
131 TSS2_RC
132 ifapi_policy_store_load_async(
133 IFAPI_POLICY_STORE *pstore,
134 IFAPI_IO *io,
135 const char *path)
136 {
137 TSS2_RC r;
138 char *abs_path = NULL;
139
140 LOG_TRACE("Load policy: %s", path);
141
142 /* Free old input buffer if buffer exists */
143 SAFE_FREE(io->char_rbuffer);
144
145 /* Convert relative path to absolute path in keystore */
146 r = policy_rel_path_to_abs_path(pstore, path, &abs_path);
147 goto_if_error2(r, "Object %s not found.", cleanup, path);
148
149 /* Prepare read operation */
150 r = ifapi_io_read_async(io, abs_path);
151
152 cleanup:
153 SAFE_FREE(abs_path);
154 return r;
155 }
156
157 /** Finish loading FAPI policy from policy store.
158 *
159 *
160 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
161 *
162 * @param[in] pstore The policy context with the policy directory.
163 * @param[in,out] io The input/output context being used for file I/O.
164 * @param[in] policy The caller allocated policy which will loaded from policy store.
165 * @retval TSS2_RC_SUCCESS After successfully loading the object.
166 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
167 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
168 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
169 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
170 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
171 * the function.
172 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
173 */
174 TSS2_RC
175 ifapi_policy_store_load_finish(
176 IFAPI_POLICY_STORE *pstore,
177 IFAPI_IO *io,
178 TPMS_POLICY *policy)
179 {
180 TSS2_RC r;
181 json_object *jso = NULL;
182 uint8_t *buffer = NULL;
183 /* ptore parameter is used to be prepared if transmission of state information
184 between async and finish will be necessary in future extensions. */
185 (void)pstore;
186
187 r = ifapi_io_read_finish(io, &buffer, NULL);
188 return_try_again(r);
189 return_if_error(r, "keystore read_finish failed");
190
191 /* If json objects can't be parse the object store is corrupted */
192 jso = json_tokener_parse((char *)buffer);
193 SAFE_FREE(buffer);
194 return_if_null(jso, "Policy store is corrupted (Json error).", TSS2_FAPI_RC_GENERAL_FAILURE);
195
196 r = ifapi_json_TPMS_POLICY_deserialize(jso, policy);
197 goto_if_error(r, "Deserialize policy", cleanup);
198
199 cleanup:
200 SAFE_FREE(buffer);
201 if (jso)
202 json_object_put(jso);
203 LOG_TRACE("Return %x", r);
204 return r;
205
206 }
207
208 /** Start writing FAPI object to the key store.
209 *
210 * The relative path will be expanded, if the default policy directory (/policy)
211 * is not part of the path.
212 *
213 * @param[in] pstore The policy context with the policy directory.
214 * @param[in] io The input/output context being used for file I/O.
215 * @param[in] path The relative path of the policy.
216 * @param[in] policy The policy to be written to the policy store.
217 * @retval TSS2_RC_SUCCESS If the policy is written successfully.
218 * @retval TSS2_FAPI_RC_IO_ERROR: If an I/O error was encountered;
219 * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated to hold the output data.
220 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
221 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
222 * the function.
223 */
224 TSS2_RC
225 ifapi_policy_store_store_async(
226 IFAPI_POLICY_STORE *pstore,
227 IFAPI_IO *io,
228 const char *path,
229 const TPMS_POLICY *policy)
230 {
231 TSS2_RC r;
232 char *jso_string = NULL;
233 json_object *jso = NULL;
234 char *abs_path = NULL;
235
236 LOG_TRACE("Store policy: %s", path);
237
238 /* Convert relative path to absolute path in the policy store */
239 r = policy_rel_path_to_abs_path(pstore, path, &abs_path);
240 goto_if_error2(r, "Path %s could not be created.", cleanup, path);
241
242 /* Generate JSON string to be written to store */
243 r = ifapi_json_TPMS_POLICY_serialize(policy, &jso);
244 goto_if_error2(r, "Policy %s could not be serialized.", cleanup, path);
245
246 jso_string = strdup(json_object_to_json_string_ext(jso,
247 JSON_C_TO_STRING_PRETTY));
248 goto_if_null2(jso_string, "Converting json to string", r, TSS2_FAPI_RC_MEMORY,
249 cleanup);
250
251 /* Start writing the json string to disk */
252 r = ifapi_io_write_async(io, abs_path, (uint8_t *) jso_string, strlen(jso_string));
253 free(jso_string);
254 goto_if_error(r, "write_async failed", cleanup);
255
256 cleanup:
257 if (jso)
258 json_object_put(jso);
259 SAFE_FREE(abs_path);
260 return r;
261 }
262
263 /** Finish writing a FAPI policy object to the policy store.
264 *
265 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
266 *
267 * @param[in] pstore The policy context with the policy directory.
268 * @param[in,out] io The input/output context being used for file I/O.
269 * @retval TSS2_RC_SUCCESS: if the function call was a success.
270 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
271 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
272 Call this function again later.
273 */
274 TSS2_RC
275 ifapi_policy_store_store_finish(
276 IFAPI_POLICY_STORE *pstore,
277 IFAPI_IO *io)
278 {
279 TSS2_RC r;
280
281 /* Pstore parameter is used to be prepared if transmission of state information
282 between async and finish will be necessary in future extensions. */
283 (void)pstore;
284 /* Finish writing the policy */
285 r = ifapi_io_write_finish(io);
286 return_try_again(r);
287
288 LOG_TRACE("Return %x", r);
289 return_if_error(r, "read_finish failed");
290
291 return TSS2_RC_SUCCESS;
292 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifndef IFAPI_POLICY_STORE_H
7 #define IFAPI_POLICY_STORE_H
8
9 #include <stdlib.h>
10
11 #include "tss2_common.h"
12 #include "tss2_tpm2_types.h"
13 #include "fapi_types.h"
14 #include "ifapi_policy_types.h"
15
16 typedef struct IFAPI_POLICY_STORE {
17 char *policydir;
18 } IFAPI_POLICY_STORE;
19
20 TSS2_RC
21 ifapi_policy_delete(
22 IFAPI_POLICY_STORE *pstore,
23 char *path);
24
25 TSS2_RC
26 ifapi_policy_store_initialize(
27 IFAPI_POLICY_STORE *pstore,
28 const char *config_policydir);
29
30 TSS2_RC
31 ifapi_policy_store_load_async(
32 IFAPI_POLICY_STORE *pstore,
33 IFAPI_IO *io,
34 const char *path);
35
36 TSS2_RC
37 ifapi_policy_store_load_finish(
38 IFAPI_POLICY_STORE *pstore,
39 IFAPI_IO *io,
40 TPMS_POLICY *policy);
41
42 TSS2_RC
43 ifapi_policy_store_store_async(
44 IFAPI_POLICY_STORE *pstore,
45 IFAPI_IO *io,
46 const char *path,
47 const TPMS_POLICY *policy);
48
49 TSS2_RC
50 ifapi_policy_store_store_finish(
51 IFAPI_POLICY_STORE *pstore,
52 IFAPI_IO *io);
53
54 #endif /* IFAPI_POLICY_STORE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef IFAPI_POLICY_TYPES_H
6 #define IFAPI_POLICY_TYPES_H
7
8 #include "tss2_tpm2_types.h"
9
10 typedef UINT32 TPMI_POLICYTYPE;
11 #define POLICYELEMENTS 0
12 #define POLICYOR 1 /**< None */
13 #define POLICYSIGNED 2 /**< None */
14 #define POLICYSECRET 3 /**< None */
15 #define POLICYPCR 4 /**< None */
16 #define POLICYLOCALITY 5 /**< None */
17 #define POLICYNV 6 /**< None */
18 #define POLICYCOUNTERTIMER 7 /**< None */
19 #define POLICYCOMMANDCODE 8 /**< None */
20 #define POLICYPHYSICALPRESENCE 9 /**< None */
21 #define POLICYCPHASH 10 /**< None */
22 #define POLICYNAMEHASH 11 /**< None */
23 #define POLICYDUPLICATIONSELECT 12 /**< None */
24 #define POLICYAUTHORIZE 13 /**< None */
25 #define POLICYAUTHVALUE 14 /**< None */
26 #define POLICYPASSWORD 15 /**< None */
27 #define POLICYNVWRITTEN 16 /**< None */
28 #define POLICYTEMPLATE 17 /**< None */
29 #define POLICYAUTHORIZENV 18 /**< None */
30 #define POLICYACTION 19 /**< None */
31
32 /** Policy type TPMS_POLICYSIGNED
33 */
34 typedef struct {
35 TPM2B_NONCE nonceTPM; /**< This is a value returned by TPM2_StartAuthSession and thus n */
36 TPM2B_DIGEST cpHashA; /**< This value will be automatically generated by the FAPI. */
37 TPM2B_NONCE policyRef; /**< Default is zero-length */
38 INT32 expiration; /**< This value will be -1 by the FAPI */
39 TPMT_SIGNATURE auth; /**< This value is generated from at runtime via a callback. */
40 TPM2B_NAME publicKey; /**< This will be automatically generated from keyPath, keyPublic */
41 char *publicKeyHint; /**< A human readable hint to denote which public key to use. */
42 char *keyPath; /**< A reference to a key inside the FAPI keystore */
43 TPMT_PUBLIC keyPublic; /**< None */
44 char *keyPEM; /**< <p>The TPM2B_NAME is constructed with a TPMT_PUBLIC from this */
45 TPMI_ALG_HASH keyPEMhashAlg; /**< (optional) Default = SHA256 */
46 TPMT_SIGNATURE signature_tpm;
47 } TPMS_POLICYSIGNED;
48
49 /** Policy type TPMS_POLICYSECRET
50 */
51 typedef struct {
52 TPM2B_NONCE nonceTPM; /**< None */
53 TPM2B_DIGEST cpHashA; /**< None */
54 TPM2B_NONCE policyRef; /**< Default is zero length */
55 INT32 expiration; /**< None */
56 char *objectPath; /**< Path of the object */
57 TPM2B_NAME objectName; /**< Public name of the object */
58 } TPMS_POLICYSECRET;
59
60 /** Policy type TPMS_POLICYLOCALITY
61 */
62 typedef struct {
63 TPMA_LOCALITY locality; /**< None */
64 } TPMS_POLICYLOCALITY;
65
66 /** Policy type TPMS_POLICYNV
67 */
68 typedef struct {
69 char *nvPath; /**< None */
70 TPMI_RH_NV_INDEX nvIndex; /**< None */
71 TPM2B_NV_PUBLIC nvPublic; /**< None */
72 TPMI_RH_NV_AUTH authHandle; /**< This is determined by FAPI at runtime. */
73 TPM2B_OPERAND operandB; /**< None */
74 UINT16 offset; /**< Default value is 0 */
75 TPM2_EO operation; /**< Default value is EQUAL */
76 } TPMS_POLICYNV;
77
78 /** Policy type TPMS_POLICYCOUNTERTIMER
79 */
80 typedef struct {
81 TPM2B_OPERAND operandB; /**< None */
82 UINT16 offset; /**< Default is 0 */
83 TPM2_EO operation; /**< None */
84 } TPMS_POLICYCOUNTERTIMER;
85
86 /** Policy type TPMS_POLICYCOMMANDCODE
87 */
88 typedef struct {
89 TPM2_CC code; /**< None */
90 } TPMS_POLICYCOMMANDCODE;
91
92 /** Policy type TPMS_POLICYPHYSICALPRESENCE
93 */
94 typedef struct {
95 } TPMS_POLICYPHYSICALPRESENCE;
96
97 /** Policy type TPMS_POLICYCPHASH
98 */
99 typedef struct {
100 TPM2B_DIGEST cpHash; /**< None */
101 } TPMS_POLICYCPHASH;
102
103 /** Policy type TPMS_POLICYNAMEHASH
104 */
105 typedef struct {
106 UINT32 count; /**< Computed during instantiation */
107 UINT32 i; /**< Temporary index for policy calculation */
108 TPM2B_NAME objectNames[3]; /**< computed during instantiation (if not initialized) */
109 char *namePaths[3]; /**< Paths of objects used for retrieving the names */
110 TPM2B_DIGEST nameHash; /**< computed during policy calculation */
111 } TPMS_POLICYNAMEHASH;
112
113 /** Policy type TPMS_POLICYDUPLICATIONSELECT
114 */
115 typedef struct {
116 TPM2B_NAME objectName; /**< Will not be used (see includeObject) */
117 TPM2B_NAME newParentName; /**< Automatically calculated */
118 TPMI_YES_NO includeObject; /**< Always NO */
119 char *newParentPath; /**< None */
120 TPM2B_PUBLIC newParentPublic; /**< None */
121 } TPMS_POLICYDUPLICATIONSELECT;
122
123 /** Policy type TPMS_POLICYAUTHORIZATION
124 */
125 typedef struct {
126 char *type; /**< tpm */
127 TPMT_PUBLIC key; /**< Selector of the algorithm used for the signature and the pub */
128 TPM2B_NONCE policyRef; /**< None */
129 TPMT_SIGNATURE signature; /**< None */
130 } TPMS_POLICYAUTHORIZATION;
131
132 typedef struct policy_object_node POLICY_OBJECT;
133
134 /** Policy type TPMS_POLICYAUTHORIZE
135 */
136 typedef struct {
137 TPM2B_DIGEST approvedPolicy; /**< None */
138 TPM2B_NONCE policyRef; /**< None */
139 TPM2B_NAME keyName; /**< Not exposed in JSON, but generated from keyPath, keyPublic o */
140 TPMT_TK_VERIFIED checkTicket; /**< None */
141 char *keyPath; /**< A reference to a key inside the FAPI keystore */
142 TPMT_PUBLIC keyPublic; /**< None */
143 char *keyPEM; /**< <p> everyone in favour<br /> The TPM2B_NAME is constructed w */
144 TPMI_ALG_HASH keyPEMhashAlg; /**< (optional) Default = SHA256 */
145 POLICY_OBJECT *policy_list;
146 TPMS_POLICYAUTHORIZATION *authorization;
147 TPMT_SIGNATURE signature;
148 } TPMS_POLICYAUTHORIZE;
149
150 /** Policy type TPMS_POLICYAUTHVALUE
151 */
152 typedef struct {
153 } TPMS_POLICYAUTHVALUE;
154
155 /** Policy type TPMS_POLICYPASSWORD
156 */
157 typedef struct {
158 } TPMS_POLICYPASSWORD;
159
160 /** Policy type TPMS_POLICYNVWRITTEN
161 */
162 typedef struct {
163 TPMI_YES_NO writtenSet; /**< Default is yes */
164 } TPMS_POLICYNVWRITTEN;
165
166 /** Policy type TPMS_POLICYTEMPLATE
167 */
168 typedef struct {
169 TPM2B_DIGEST templateHash; /**< None */
170 TPM2B_PUBLIC templatePublic; /**< None */
171 char *templateName; /**< None */
172 } TPMS_POLICYTEMPLATE;
173
174 /** Policy type TPMS_POLICYAUTHORIZENV
175 */
176 typedef struct {
177 char *nvPath; /**< None */
178 TPM2B_NV_PUBLIC nvPublic; /**< None */
179 TPM2B_DIGEST policy; /**< Policy Digest */
180 TPMT_HA nv_policy; /**< Policy stored in NV ram */
181 uint8_t *policy_buffer;
182 } TPMS_POLICYAUTHORIZENV;
183
184 /** Policy type TPMS_POLICYACTION
185 */
186 typedef struct {
187 char *action; /**< The FAPI will return a string representation of the JSON sub */
188 } TPMS_POLICYACTION;
189
190 /** Policy type TPMS_PCRVALUE
191 */
192 typedef struct {
193 UINT32 pcr; /**< None */
194 TPM2_ALG_ID hashAlg; /**< None */
195 TPMU_HA digest; /**< None */
196 } TPMS_PCRVALUE;
197
198 /** Policy type TPML_PCRVALUES
199 */
200 typedef struct TPML_PCRVALUES {
201 UINT32 count; /**< None */
202 TPMS_PCRVALUE pcrs[]; /**< Array of pcr values */
203 } TPML_PCRVALUES;
204
205 /** Policy type TPMS_POLICYPCR
206 */
207 typedef struct {
208 struct TPML_PCRVALUES *pcrs; /**< None */
209 TPMS_PCR_SELECT currentPCRs; /**< The hashAlg are inferred from */
210 TPML_PCR_SELECTION currentPCRandBanks; /**< Complete selection with banks */
211 } TPMS_POLICYPCR;
212
213 /** Policy type TPML_POLICYAUTHORIZATIONS
214 */
215 typedef struct TPML_POLICYAUTHORIZATIONS {
216 UINT32 count; /**< None */
217 TPMS_POLICYAUTHORIZATION authorizations[]; /**< Array of policy elements */
218 } TPML_POLICYAUTHORIZATIONS;
219
220 typedef struct TPML_POLICYELEMENTS TPML_POLICYELEMENTS;
221
222 /** Policy type TPMS_POLICYBRANCH
223 */
224 typedef struct {
225 char *name; /**< None */
226 char *description; /**< None */
227 TPML_DIGEST_VALUES policyDigests;
228 struct TPML_POLICYELEMENTS *policy; /**< Array of policy elements */
229 } TPMS_POLICYBRANCH;
230
231 /** Policy type TPML_POLICYBRANCHES
232 */
233 typedef struct TPML_POLICYBRANCHES {
234 UINT32 count; /**< None */
235 TPMS_POLICYBRANCH authorizations[]; /**< Array of policy elements */
236 } TPML_POLICYBRANCHES;
237
238 /** Policy type TPMS_POLICYOR
239 */
240 typedef struct {
241 struct TPML_POLICYBRANCHES *branches; /**< An (infinite) array of policy elements. This does not contai */
242 } TPMS_POLICYOR;
243
244 /** [u'']
245 */
246 typedef union {
247 TPMS_POLICYOR PolicyOr; /**< None */
248 TPMS_POLICYSIGNED PolicySigned; /**< None */
249 TPMS_POLICYSECRET PolicySecret; /**< None */
250 TPMS_POLICYPCR PolicyPCR; /**< None */
251 TPMS_POLICYLOCALITY PolicyLocality; /**< None */
252 TPMS_POLICYNV PolicyNV; /**< None */
253 TPMS_POLICYCOUNTERTIMER PolicyCounterTimer; /**< None */
254 TPMS_POLICYCOMMANDCODE PolicyCommandCode; /**< None */
255 TPMS_POLICYPHYSICALPRESENCE PolicyPhysicalPresence; /**< None */
256 TPMS_POLICYCPHASH PolicyCpHash; /**< None */
257 TPMS_POLICYNAMEHASH PolicyNameHash; /**< None */
258 TPMS_POLICYDUPLICATIONSELECT PolicyDuplicationSelect; /**< None */
259 TPMS_POLICYAUTHORIZE PolicyAuthorize; /**< None */
260 TPMS_POLICYAUTHVALUE PolicyAuthValue; /**< None */
261 TPMS_POLICYPASSWORD PolicyPassword; /**< None */
262 TPMS_POLICYNVWRITTEN PolicyNvWritten; /**< None */
263 TPMS_POLICYTEMPLATE PolicyTemplate; /**< None */
264 TPMS_POLICYAUTHORIZENV PolicyAuthorizeNv; /**< None */
265 TPMS_POLICYACTION PolicyAction; /**< None */
266 } TPMU_POLICYELEMENT;
267
268 /** Policy type TPMT_POLICYELEMENT
269 */
270 typedef struct {
271 TPMI_POLICYTYPE type; /**< None */
272 TPML_DIGEST_VALUES policyDigests; /**< None */
273 TPMU_POLICYELEMENT element; /**< The union does is not embedded inside a field. */
274 } TPMT_POLICYELEMENT;
275
276 /** Policy type TPML_POLICYELEMENTS
277 */
278 struct TPML_POLICYELEMENTS {
279 UINT32 count; /**< None */
280 TPMT_POLICYELEMENT elements[]; /**< Array of policy elements */
281 };
282
283 /** Policy type TPMS_POLICY
284 */
285 typedef struct TPMS_POLICY {
286 char *description; /**< O */
287 TPML_DIGEST_VALUES policyDigests; /**< O */
288 struct TPML_POLICYAUTHORIZATIONS *policyAuthorizations; /**< O */
289 struct TPML_POLICYELEMENTS *policy; /**< X */
290 } TPMS_POLICY;
291
292 #endif /* IFAPI_POLICY_TYPES_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "tss2_mu.h"
14 #include "fapi_util.h"
15 #include "fapi_crypto.h"
16 //#include "fapi_policy.h"
17 #include "ifapi_policy_execute.h"
18 #include "ifapi_policyutil_execute.h"
19 #include "ifapi_helpers.h"
20 #include "ifapi_json_deserialize.h"
21 #include "tpm_json_deserialize.h"
22 #include "ifapi_policy_callbacks.h"
23 #include "ifapi_policyutil_execute.h"
24 #define LOGMODULE fapi
25 #include "util/log.h"
26 #include "util/aux_util.h"
27
28 /** Create a new policy on policy stack.
29 *
30 * The structures for policy and callback execution are allocated
31 * and the callbacks are assigned.
32 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
33 */
34 static TSS2_RC
35 new_policy(
36 FAPI_CONTEXT *context,
37 TPMS_POLICY *policy,
38 IFAPI_POLICYUTIL_STACK **current_policy)
39 {
40 LOG_DEBUG("ADD POLICY");
41 IFAPI_POLICY_EXEC_CTX *pol_exec_ctx;
42 IFAPI_POLICY_EXEC_CB_CTX *pol_exec_cb_ctx;
43
44 *current_policy = calloc(sizeof(IFAPI_POLICYUTIL_STACK), 1);
45 if (!*current_policy) {
46 return_error(TSS2_FAPI_RC_MEMORY, "Out of memory");
47 }
48
49 pol_exec_ctx = calloc(sizeof(IFAPI_POLICY_EXEC_CTX), 1);
50 if (!pol_exec_ctx) {
51 return_error(TSS2_FAPI_RC_MEMORY, "Out of memory");
52 }
53 (*current_policy)->pol_exec_ctx = pol_exec_ctx;
54 pol_exec_ctx->callbacks.cbauth = ifapi_policyeval_cbauth;
55 pol_exec_ctx->callbacks.cbauth_userdata = context;
56 pol_exec_ctx->callbacks.cbpolsel = ifapi_branch_selection;
57 pol_exec_ctx->callbacks.cbpolsel_userdata = context;
58 pol_exec_ctx->callbacks.cbsign = ifapi_sign_buffer;
59 pol_exec_ctx->callbacks.cbsign_userdata = context;
60 pol_exec_ctx->callbacks.cbauthpol = ifapi_exec_auth_policy;
61 pol_exec_ctx->callbacks.cbauthpol_userdata = context;
62 pol_exec_ctx->callbacks.cbauthnv = ifapi_exec_auth_nv_policy;
63 pol_exec_ctx->callbacks.cbauthnv_userdata = context;
64 pol_exec_ctx->callbacks.cbdup = ifapi_get_duplicate_name;
65 pol_exec_ctx->callbacks.cbdup_userdata = context;
66 pol_exec_ctx->callbacks.cbaction = ifapi_policy_action;
67 pol_exec_ctx->callbacks.cbaction_userdata = context;
68
69 pol_exec_cb_ctx = calloc(sizeof(IFAPI_POLICY_EXEC_CB_CTX), 1);
70 if (!pol_exec_cb_ctx) {
71 return_error(TSS2_FAPI_RC_MEMORY, "Out of memory");
72 }
73 pol_exec_ctx->app_data = pol_exec_cb_ctx;
74 pol_exec_ctx->policy = policy;
75 if (!context->policy.policyutil_stack) {
76 context->policy.policyutil_stack = *current_policy;
77 context->policy.util_current_policy = *current_policy;
78 } else {
79 context->policy.util_current_policy->next = *current_policy;
80 (*current_policy)->prev = context->policy.util_current_policy;
81 }
82 return TSS2_RC_SUCCESS;
83 }
84
85 /** Compute a new session which will be uses as policy session.
86 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
87 * this function needs to be called again.
88 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
89 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
90 */
91 static TSS2_RC
92 create_session(
93 FAPI_CONTEXT *context,
94 ESYS_TR *session,
95 TPMI_ALG_HASH hash_alg)
96 {
97 TSS2_RC r = TSS2_RC_SUCCESS;
98
99 switch (context->policy.create_session_state) {
100 case CREATE_SESSION_INIT:
101 r = Esys_StartAuthSession_Async(context->esys,
102 context->srk_handle ? context->srk_handle : ESYS_TR_NONE,
103 ESYS_TR_NONE,
104 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
105 NULL,
106 TPM2_SE_POLICY,
107 &context->profiles.default_profile.session_symmetric,
108 hash_alg);
109
110 return_if_error(r, "Creating session.");
111
112 context->policy.create_session_state = WAIT_FOR_CREATE_SESSION;
113 return TSS2_FAPI_RC_TRY_AGAIN;
114
115 case WAIT_FOR_CREATE_SESSION:
116 r = Esys_StartAuthSession_Finish(context->esys, session);
117 if (r != TSS2_RC_SUCCESS)
118 return r;
119 context->policy.create_session_state = CREATE_SESSION_INIT;
120 break;
121
122 default:
123 context->state = _FAPI_STATE_INTERNALERROR;
124 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid state for create session.",
125 cleanup);
126 }
127
128 cleanup:
129 return r;
130 }
131
132 /** Cleanup the current policy and adapt the policy stack.
133 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
134 */
135 static TSS2_RC
136 clear_current_policy(FAPI_CONTEXT *context)
137 {
138 LOG_DEBUG("CLEAR POLICY");
139 IFAPI_POLICYUTIL_STACK *prev_pol;
140 if (!context->policy.util_current_policy) {
141 return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "No current policy.");
142 }
143 prev_pol = context->policy.util_current_policy->prev;
144
145 SAFE_FREE(context->policy.util_current_policy->pol_exec_ctx->app_data);
146 SAFE_FREE(context->policy.util_current_policy->pol_exec_ctx);
147 SAFE_FREE(context->policy.util_current_policy);
148
149 if (!prev_pol) {
150 context->policy.policyutil_stack = NULL;
151 } else {
152 prev_pol->next = NULL;
153 }
154 return TSS2_RC_SUCCESS;
155 }
156
157 /** Cleanup the policy stack.
158 *
159 * Will be used if an error occurs.
160 */
161 static void
162 clear_all_policies(FAPI_CONTEXT *context)
163 {
164 LOG_DEBUG("CLEAR ALL POLICIES");
165
166 IFAPI_POLICYUTIL_STACK *policy = context->policy.policyutil_stack;
167 IFAPI_POLICYUTIL_STACK *next_policy;
168
169 while (policy) {
170 next_policy = policy->next;
171 SAFE_FREE(policy->pol_exec_ctx->app_data);
172 if (policy->pol_exec_ctx->session)
173 Esys_FlushContext(context->esys, policy->pol_exec_ctx->session);
174 SAFE_FREE(policy->pol_exec_ctx);
175 ;
176 SAFE_FREE(policy);
177 policy = next_policy;
178 }
179 context->policy.policyutil_stack = NULL;
180 }
181
182 /** Prepare the execution of a new policy on policy stack.
183 *
184 * The context for the policy utility, the policy execution and the needed
185 * callbacks is initialized.
186 * The policy execution will be prepared. In this step the list of policies
187 * to be executed will be computed.
188 * @param[in,out] context The fapi context with the pointer to the policy stack.
189 * @param[in] hash_alg The hash algorithm used for the policy computation.
190 * @param[in,out] policy The policy to be executed. Some policy elements will
191 * be used to store computed parameters needed for policy
192 * execution.
193 * @retval TSS2_RC_SUCCESS on success.
194 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for branch selection is
195 * not defined. This callback will be needed of or policies have to be
196 * executed.
197 * @retval TSS2_FAPI_RC_BAD_VALUE If the computed branch index deliverd by the
198 * callback does not identify a branch.
199 * @retval TSS2_FAPI_RC_BAD_REFERENCE If no context is passed.
200 *
201 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
202 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
203 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
204 */
205 TSS2_RC
206 ifapi_policyutil_execute_prepare(
207 FAPI_CONTEXT *context,
208 TPMI_ALG_HASH hash_alg,
209 TPMS_POLICY *policy)
210 {
211 TSS2_RC r;
212 IFAPI_POLICYUTIL_STACK *current_policy;
213
214 return_if_null(context, "Bad context.", TSS2_FAPI_RC_BAD_REFERENCE);
215
216 r = new_policy(context, policy, &current_policy);
217 goto_if_error(r, "Create new policy.", error);
218
219 r = ifapi_policyeval_execute_prepare(current_policy->pol_exec_ctx, hash_alg, policy);
220 goto_if_error(r, "Prepare policy execution.", error);
221
222 return r;
223
224 error:
225 while (context->policy.policyutil_stack) {
226 clear_all_policies(context);
227 }
228 SAFE_FREE(current_policy);
229 return r;
230 }
231 /** State machine to Execute the TPM policy commands needed for the current policy.
232 *
233 * In the first step a session will be created if no session is passed.
234 * In the second step the policy engine will execute the policy.
235 *
236 * @param[in,out] context The fapi context with the pointer to the policy stack.
237 * @param[in,out] session The policy session to be extended or if the value is
238 * equal zero or ESYS_TR_NONE a new created session will been
239 * be stored in this parameter.
240 * @retval TSS2_RC_SUCCESS on success.
241 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
242 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
243 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
244 * store.
245 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
246 * not successful.
247 * @retval TSS2_FAPI_RC_BAD_TEMPLATE In a invalid policy is loaded during execution.
248 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
249 * execution fails.
250 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
251 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
252 * this function needs to be called again.
253 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
254 * operation already pending.
255 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
256 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
257 * during authorization.
258 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
259 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
260 * is not set.
261 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
262 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
263 */
264 TSS2_RC
265 ifapi_policyutil_execute(FAPI_CONTEXT *context, ESYS_TR *session)
266 {
267 TSS2_RC r;
268 IFAPI_POLICYUTIL_STACK *pol_util_ctx;
269 TPMI_ALG_HASH hash_alg;
270
271 if (context->policy.util_current_policy) {
272 pol_util_ctx = context->policy.util_current_policy->next;
273 context->policy.util_current_policy = context->policy.util_current_policy->next;
274 } else {
275 pol_util_ctx = context->policy.policyutil_stack;
276 context->policy.util_current_policy = pol_util_ctx;
277 }
278 LOG_TRACE("Util context: %p", pol_util_ctx);
279
280 if (!pol_util_ctx) {
281 return_error(TSS2_FAPI_RC_GENERAL_FAILURE, "No policy util stack.");
282 }
283
284 switch (pol_util_ctx->state) {
285 statecase(pol_util_ctx->state, POLICY_UTIL_INIT);
286 LOG_DEBUG("Util session: %x", pol_util_ctx->policy_session);
287 if (*session == ESYS_TR_NONE || *session == 0) {
288 /* Create a new policy session for the current policy execution */
289 hash_alg = pol_util_ctx->pol_exec_ctx->hash_alg;
290 r = create_session(context, &pol_util_ctx->policy_session,
291 hash_alg);
292 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
293 context->policy.util_current_policy = pol_util_ctx->prev;
294 return TSS2_FAPI_RC_TRY_AGAIN;
295 }
296 goto_if_error(r, "Create policy session", error);
297
298 pol_util_ctx->pol_exec_ctx->session = pol_util_ctx->policy_session;
299 } else {
300 pol_util_ctx->pol_exec_ctx->session = *session;
301 }
302 fallthrough;
303
304 statecase(pol_util_ctx->state, POLICY_UTIL_EXEC_POLICY);
305 r = ifapi_policyeval_execute(context->esys,
306 pol_util_ctx->pol_exec_ctx);
307 if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
308 context->policy.util_current_policy = pol_util_ctx->prev;
309 return TSS2_FAPI_RC_TRY_AGAIN;
310 }
311 goto_if_error(r, "Execute policy.", error);
312
313 break;
314
315 statecasedefault(pol_util_ctx->state);
316 }
317 *session = pol_util_ctx->policy_session;
318
319 pol_util_ctx = pol_util_ctx->prev;
320
321 r = clear_current_policy(context);
322 goto_if_error(r, "Clear policy.", error);
323
324 context->policy.util_current_policy = pol_util_ctx;
325
326 LOG_TRACE("success");
327 return r;
328
329 error:
330 while (context->policy.policyutil_stack) {
331 clear_all_policies(context);
332 }
333 return r;
334 }
0 /*******************************************************************************
1 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
2 * All rights reserved.
3 *******************************************************************************/
4 #ifndef FAPI_POLICYUTIL_EXECUTE_H
5 #define FAPI_POLICYUTIL_EXECUTE_H
6
7 #include <stdint.h>
8 #include <stdarg.h>
9 #include <stdbool.h>
10 #include <sys/stat.h>
11 #include <json-c/json.h>
12 #include <json-c/json_util.h>
13
14 #include "tss2_esys.h"
15 #include "tss2_fapi.h"
16
17
18 /** The states for the FAPI's policy util execution */
19 enum IFAPI_STATE_POLICY_UTIL_EXEC {
20 POLICY_UTIL_INIT,
21 POLICY_UTIL_EXEC_POLICY,
22 };
23
24 /** The context of the policy execution */
25 struct IFAPI_POLICYUTIL_STACK {
26 ESYS_TR policy_session; /**< The policy session created for the current evaluation */
27 IFAPI_POLICY_EXEC_CTX *pol_exec_ctx; /**< The execution context for the current policy */
28 enum IFAPI_STATE_POLICY_UTIL_EXEC state;
29 IFAPI_POLICYUTIL_STACK *next; /**< Pointer to next policy */
30 IFAPI_POLICYUTIL_STACK *prev; /**< Pointer to previous policy */
31 };
32
33 TSS2_RC
34 ifapi_policyutil_execute_prepare(
35 FAPI_CONTEXT *context,
36 TPMI_ALG_HASH hash_alg,
37 TPMS_POLICY *policy);
38
39 TSS2_RC
40 ifapi_policyutil_execute(
41 FAPI_CONTEXT *context,
42 ESYS_TR *session);
43
44 #endif /* FAPI_POLICYUTIL_EXECUTE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "tss2_common.h"
15
16 #include "ifapi_profiles.h"
17
18 #include "tpm_json_deserialize.h"
19 #include "ifapi_policy_json_deserialize.h"
20 #include "ifapi_json_deserialize.h"
21 #include "ifapi_helpers.h"
22 #define LOGMODULE fapi
23 #include "util/log.h"
24 #include "util/aux_util.h"
25 #include "ifapi_macros.h"
26
27 #define PROFILES_EXTENSION ".json"
28 #define PROFILES_PREFIX "P_"
29
30 static TSS2_RC
31 ifapi_profile_json_deserialize(
32 json_object *jso,
33 IFAPI_PROFILE *profile);
34
35 static TSS2_RC
36 ifapi_profile_checkpcrs(const TPML_PCR_SELECTION *pcr_profile);
37
38 /** Initialize the profiles information in the context in an asynchronous way
39 *
40 * Load the profile information from disk, fill the dictionary of loaded profiles and fill
41 * the default profile information into the context.
42 *
43 * Call ifapi_profiles_initialize_finish to complete the operation.
44 *
45 * @param[in,out] profiles The context for the profiles information.
46 * @param[in,out] io The input/output context being used for file I/O.
47 * @param[in] profilesdir The directory to load profile information from.
48 * @param[in] defaultprofile The name of the default profile to use.
49 * @retval TSS2_RC_SUCCESS on success.
50 * @retval TSS2_FAPI_RC_BAD_REFERENCE if NULL pointers were passed in.
51 * @retval TSS2_FAPI_RC_BAD_VALUE if the profilesdir does not exist or is empty.
52 * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
53 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
54 */
55 TSS2_RC
56 ifapi_profiles_initialize_async(
57 IFAPI_PROFILES *profiles,
58 IFAPI_IO *io,
59 const char *profilesdir,
60 const char *defaultprofile)
61 {
62 TSS2_RC r;
63 char *tmp;
64 size_t i, j;
65 check_not_null(profiles);
66 check_not_null(profilesdir);
67
68 memset(profiles, 0, sizeof(*profiles));
69
70 profiles->default_name = strdup(defaultprofile);
71 check_oom(profiles->default_name);
72
73 r = ifapi_io_dirfiles(profilesdir, &profiles->filenames, &profiles->num_profiles);
74 return_if_error(r, "Reading profiles from profiles dir");
75
76 profiles->profiles = calloc(profiles->num_profiles, sizeof(profiles->profiles[0]));
77 check_oom(profiles->profiles);
78
79 /* Clean up list of files to only include those that match our filename pattern
80 Expand the filenames with the directory
81 Set the names in the dictionary */
82 for (i = 0; i < profiles->num_profiles; ) {
83 char *ext = strstr(profiles->filenames[i], PROFILES_EXTENSION);
84 /* Path the filename with the expected pattern */
85 if (ext != NULL && strlen(ext) == strlen(PROFILES_EXTENSION) &&
86 strncmp(profiles->filenames[i], PROFILES_PREFIX, strlen(PROFILES_PREFIX)) == 0)
87 {
88 LOG_TRACE("Using file %s in profiles directory", profiles->filenames[i]);
89 /* Add the profile name */
90 profiles->profiles[i].name = strndup(profiles->filenames[i],
91 ext - profiles->filenames[i]);
92 check_oom(profiles->profiles[i].name);
93 /* Expand the filename with the directory */
94 tmp = profiles->filenames[i];
95 r = ifapi_asprintf(&profiles->filenames[i], "%s/%s", profilesdir, tmp);
96 return_if_error(r, "Out of memory");
97
98 LOG_TRACE("Added profile-entry %s for file %s based on direntry %s",
99 profiles->profiles[i].name, profiles->filenames[i], tmp);
100
101 /* Cleanup and continue */
102 free(tmp);
103 i++;
104 } else {
105 LOG_TRACE("Skipping file %s in profiles directory", profiles->filenames[i]);
106 free(profiles->filenames[i]);
107 profiles->num_profiles -= 1;
108 for (j = i; j < profiles->num_profiles; j++) {
109 profiles->filenames[j] = profiles->filenames[j + 1];
110 }
111 }
112 }
113
114 if (profiles->num_profiles == 0) {
115 LOG_ERROR("No files found in profile dir %s that match the pattern %s*%s",
116 profilesdir, PROFILES_PREFIX, PROFILES_EXTENSION);
117 return TSS2_FAPI_RC_BAD_VALUE;
118 }
119 #ifdef HAVE_REALLOCARRAY
120 profiles->profiles = reallocarray(profiles->profiles, profiles->num_profiles,
121 sizeof(profiles->profiles[0]));
122 profiles->filenames = reallocarray(profiles->filenames, profiles->num_profiles,
123 sizeof(profiles->filenames[0]));
124 #else /* HAVE_REALLOCARRAY */
125 profiles->profiles = realloc(profiles->profiles, profiles->num_profiles *
126 sizeof(profiles->profiles[0]));
127 profiles->filenames = realloc(profiles->filenames, profiles->num_profiles *
128 sizeof(profiles->filenames[0]));
129 #endif /* HAVE_REALLOCARRAY */
130 /* No need for OOM checks, since num_profiles may only have become smaller */
131
132 r = ifapi_io_read_async(io, profiles->filenames[profiles->profiles_idx]);
133 return_if_error2(r, "Reading profile %s", profiles->filenames[profiles->profiles_idx]);
134
135 return TSS2_RC_SUCCESS;
136 }
137
138 /** Initialize the profiles information in the context in an asynchronous way
139 *
140 * Call after ifapi_profiles_initialize_async to complete the operation.
141 *
142 * @param[in,out] profiles The context for the profiles information.
143 * @param[in,out] io The input/output context being used for file I/O.
144 * @retval TSS2_RC_SUCCESS on success.
145 * @retval TSS2_FAPI_RC_BAD_REFERENCE if NULL pointers were passed in.
146 * @retval TSS2_FAPI_RC_BAD_VALUE if a profile could not be loaded.
147 * @retval TSS2_FAPI_RC_IO_ERROR if creation of log_dir failed or log_dir is not writable.
148 * @retval TSS2_FAPI_RC_MEMORY if memory allocation failed.
149 * @retval TSS2_FAPI_RC_TRY_AGAIN if the I/O operation is not finished yet and this function needs
150 * to be called again.
151 */
152 TSS2_RC
153 ifapi_profiles_initialize_finish(
154 IFAPI_PROFILES *profiles,
155 IFAPI_IO *io)
156 {
157 TSS2_RC r;
158 uint8_t *buffer;
159 size_t i;
160 json_object *jso;
161 check_not_null(profiles);
162 check_not_null(io);
163
164 r = ifapi_io_read_finish(io, &buffer, NULL);
165 return_if_error(r, "Reading profile failed");
166
167 jso = json_tokener_parse((char *) buffer);
168 free(buffer);
169 if (jso == NULL) {
170 LOG_ERROR("Failed to parse profile %s", profiles->filenames[profiles->profiles_idx]);
171 return TSS2_FAPI_RC_BAD_VALUE;
172 }
173
174 r = ifapi_profile_json_deserialize(jso,
175 &profiles->profiles[profiles->profiles_idx].profile);
176 json_object_put(jso);
177 return_if_error2(r, "Parsing profile %s failed",
178 profiles->filenames[profiles->profiles_idx]);
179
180 r = ifapi_profile_checkpcrs(&profiles->profiles[profiles->profiles_idx].profile.pcr_selection);
181 return_if_error2(r, "Malformed profile pcr selection for profile %s",
182 profiles->filenames[profiles->profiles_idx]);
183
184 profiles->profiles_idx += 1;
185
186 if (profiles->profiles_idx < profiles->num_profiles) {
187 r = ifapi_io_read_async(io, profiles->filenames[profiles->profiles_idx]);
188 return_if_error2(r, "Reading profile %s", profiles->filenames[profiles->profiles_idx]);
189
190 return TSS2_FAPI_RC_TRY_AGAIN;
191 }
192
193 /* Get the data of the default profile into the respective variable */
194 for (i = 0; i < profiles->num_profiles; i++) {
195 if (strcmp(profiles->default_name, profiles->profiles[i].name) == 0) {
196 profiles->default_profile = profiles->profiles[i].profile;
197 break;
198 }
199 }
200 if (i == profiles->num_profiles) {
201 LOG_ERROR("Default profile %s not in the list of loaded profiles",
202 profiles->default_name);
203 return TSS2_FAPI_RC_BAD_VALUE;
204 }
205
206 for (i = 0; i < profiles->num_profiles; i++) {
207 free(profiles->filenames[i]);
208 }
209 SAFE_FREE(profiles->filenames);
210
211 return TSS2_RC_SUCCESS;
212 }
213
214 /** Return the profile data for a given profile name.
215 *
216 * Returns a (const, not to be free'd) pointer to the profile data for a requested profile.
217 * If a NULL profile is requesten, then the default profile is returned.
218 * If a keypath is passed in, then the prefix is analysed. If that keypath starts with a profile
219 * then this profile is returned. Otherwise the default profile is returned.
220 *
221 * @param[in] profiles The profiles context
222 * @param[in] name The name of the profile or the keypath
223 * @param[out] profile The pointer to the profile data.
224 * @retval TSS2_RC_SUCCESS on success.
225 * @retval TSS2_FAPI_RC_BAD_REFERENCE if NULL pointers were passed in.
226 * @retval TSS2_FAPI_RC_BAD_VALUE if a profile is not found.
227 */
228 TSS2_RC
229 ifapi_profiles_get(
230 const IFAPI_PROFILES *profiles,
231 const char *name,
232 const IFAPI_PROFILE **profile)
233 {
234 check_not_null(profiles);
235 check_not_null(name);
236 check_not_null(profile);
237 char *split;
238 size_t len;
239
240 /* if no name or nor profile prefix is given, use the default profile */
241 if (!name || strncmp(name, "P_", 2) != 0 || strncmp(name, "/P_", 2) != 0) {
242 *profile = &profiles->default_profile;
243 return TSS2_RC_SUCCESS;
244 }
245
246 /* Search for path delimiter */
247 split = index(name, IFAPI_FILE_DELIM_CHAR);
248
249 /* If the path beging with delimiters, skip over those */
250 if (name == split) {
251 name += 1;
252 split = index(name, IFAPI_FILE_DELIM_CHAR);
253 }
254 if (split == NULL)
255 len = strlen(name);
256 else
257 len = split - name;
258
259 for (size_t i = 0; i < profiles->num_profiles; i++) {
260 if (len == strlen(profiles->profiles[i].name) &&
261 strncmp(name, profiles->profiles[i].name, len) == 0) {
262 *profile = &profiles->profiles[i].profile;
263 return TSS2_RC_SUCCESS;
264 }
265 }
266 LOG_ERROR("Profile %s not in the list of loaded profiles", name);
267 return TSS2_FAPI_RC_BAD_VALUE;
268 }
269
270 /** Sanitizes and frees internal data structures of loaded profiles' information.
271 *
272 * @param[in,out] profiles The context for the profiles information.
273 */
274 void
275 ifapi_profiles_finalize(
276 IFAPI_PROFILES *profiles)
277 {
278 size_t i;
279 if (!profiles) {
280 LOG_ERROR("Called with bad reference");
281 return;
282 }
283
284 SAFE_FREE(profiles->default_name);
285
286 for (i = 0; i < profiles->num_profiles; i++) {
287 IFAPI_PROFILE_ENTRY * entry = &profiles->profiles[i];
288 SAFE_FREE(profiles->profiles[i].name);
289
290 IFAPI_PROFILE * profile = &entry->profile;
291
292 SAFE_FREE(profile->srk_template);
293 SAFE_FREE(profile->ek_template);
294
295 ifapi_cleanup_policy(profile->eh_policy);
296 SAFE_FREE(profile->eh_policy);
297
298 ifapi_cleanup_policy(profile->ek_policy);
299 SAFE_FREE(profile->ek_policy);
300
301 ifapi_cleanup_policy(profile->sh_policy);
302 SAFE_FREE(profile->sh_policy);
303 }
304 SAFE_FREE(profiles->profiles);
305
306 memset(profiles, 0, sizeof(*profiles));
307 }
308
309 /** Deserialize a IFAPI_KEY_PROFILE json object.
310 *
311 * @param[in] jso the json object to be deserialized.
312 * @param[out] out the deserialzed binary object.
313 * @retval TSS2_RC_SUCCESS if the function call was a success.
314 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
315 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
316 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
317 * object store.
318 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
319 */
320 static TSS2_RC
321 ifapi_profile_json_deserialize(
322 json_object *jso,
323 IFAPI_PROFILE *out)
324 {
325 json_object *jso2;
326 TSS2_RC r;
327
328 const TPMT_SYM_DEF session_symmetric_default = {
329 .algorithm = TPM2_ALG_AES,
330 .keyBits = {.aes = 128},
331 .mode = {.aes = TPM2_ALG_CFB}
332 };
333
334 LOG_TRACE("call");
335 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
336
337 if (!ifapi_get_sub_object(jso, "type", &jso2)) {
338 LOG_ERROR("Bad value");
339 return TSS2_FAPI_RC_BAD_VALUE;
340 }
341 r = ifapi_json_TPMI_ALG_PUBLIC_deserialize(jso2, &out->type);
342 return_if_error(r, "BAD VALUE");
343
344 if (!ifapi_get_sub_object(jso, "srk_template", &jso2)) {
345 LOG_ERROR("Bad value");
346 return TSS2_FAPI_RC_BAD_VALUE;
347 }
348 out->srk_template = strdup(json_object_get_string(jso2));
349 return_if_null(out->srk_template, "Out of memory.", TSS2_FAPI_RC_MEMORY);
350
351 if (!ifapi_get_sub_object(jso, "ek_template", &jso2)) {
352 LOG_ERROR("Bad value");
353 return TSS2_FAPI_RC_BAD_VALUE;
354 }
355 out->ek_template = strdup(json_object_get_string(jso2));
356 return_if_null(out->ek_template, "Out of memory.", TSS2_FAPI_RC_MEMORY);
357
358 if (!ifapi_get_sub_object(jso, "ecc_signing_scheme", &jso2)) {
359 memset(&out->ecc_signing_scheme, 0, sizeof(TPMT_SIG_SCHEME));
360 } else {
361 r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->ecc_signing_scheme);
362 return_if_error(r, "BAD VALUE");
363 }
364
365 if (!ifapi_get_sub_object(jso, "rsa_signing_scheme", &jso2)) {
366 memset(&out->rsa_signing_scheme, 0, sizeof(TPMT_SIG_SCHEME));
367 } else {
368 r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->rsa_signing_scheme);
369 return_if_error(r, "BAD VALUE");
370 }
371
372 if (!ifapi_get_sub_object(jso, "rsa_decrypt_scheme", &jso2)) {
373 memset(&out->rsa_decrypt_scheme, 0, sizeof(TPMT_RSA_DECRYPT));
374 } else {
375 r = ifapi_json_TPMT_RSA_DECRYPT_deserialize(jso2, &out->rsa_decrypt_scheme);
376 return_if_error(r, "BAD VALUE");
377 }
378
379 if (!ifapi_get_sub_object(jso, "sym_mode", &jso2)) {
380 LOG_ERROR("Bad value");
381 return TSS2_FAPI_RC_BAD_VALUE;
382 }
383 r = ifapi_json_TPMI_ALG_SYM_MODE_deserialize(jso2, &out->sym_mode);
384 return_if_error(r, "BAD VALUE");
385
386 if (!ifapi_get_sub_object(jso, "sym_parameters", &jso2)) {
387 LOG_ERROR("Bad value");
388 return TSS2_FAPI_RC_BAD_VALUE;
389 }
390 r = ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(jso2, &out->sym_parameters);
391 return_if_error(r, "BAD VALUE");
392
393 if (!ifapi_get_sub_object(jso, "sym_block_size", &jso2)) {
394 LOG_ERROR("Bad value");
395 return TSS2_FAPI_RC_BAD_VALUE;
396 }
397 r = ifapi_json_UINT16_deserialize(jso2, &out->sym_block_size);
398 return_if_error(r, "BAD VALUE");
399
400 if (!ifapi_get_sub_object(jso, "pcr_selection", &jso2)) {
401 LOG_ERROR("Bad value");
402 return TSS2_FAPI_RC_BAD_VALUE;
403 }
404 r = ifapi_json_TPML_PCR_SELECTION_deserialize(jso2, &out->pcr_selection);
405 return_if_error(r, "BAD VALUE");
406
407 if (!ifapi_get_sub_object(jso, "nameAlg", &jso2)) {
408 LOG_ERROR("Bad value");
409 return TSS2_FAPI_RC_BAD_VALUE;
410 }
411 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->nameAlg);
412 return_if_error(r, "BAD VALUE");
413
414 if (out->type == TPM2_ALG_RSA) {
415 if (!ifapi_get_sub_object(jso, "exponent", &jso2)) {
416 LOG_ERROR("Bad value");
417 return TSS2_FAPI_RC_BAD_VALUE;
418 }
419 r = ifapi_json_UINT32_deserialize(jso2, &out->exponent);
420 return_if_error(r, "BAD VALUE");
421 if (!ifapi_get_sub_object(jso, "keyBits", &jso2)) {
422 LOG_ERROR("Bad value");
423 return TSS2_FAPI_RC_BAD_VALUE;
424
425 }
426 r = ifapi_json_TPMI_RSA_KEY_BITS_deserialize(jso2, &out->keyBits);
427 return_if_error(r, "BAD VALUE");
428
429 } else if (out->type == TPM2_ALG_ECC) {
430 if (!ifapi_get_sub_object(jso, "curveID", &jso2)) {
431 LOG_ERROR("Bad value");
432 return TSS2_FAPI_RC_BAD_VALUE;
433 }
434 r = ifapi_json_TPMI_ECC_CURVE_deserialize(jso2, &out->curveID);
435 return_if_error(r, "BAD VALUE");
436 }
437
438 if (!ifapi_get_sub_object(jso, "session_symmetric", &jso2)) {
439 out->session_symmetric = session_symmetric_default;
440 } else {
441 r = ifapi_json_TPMT_SYM_DEF_deserialize(jso2, &out->session_symmetric);
442 return_if_error(r, "BAD VALUE");
443 }
444
445 if (ifapi_get_sub_object(jso, "eh_policy", &jso2)) {
446 out->eh_policy = calloc(1, sizeof(TPMS_POLICY));
447 goto_if_null2(out->eh_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
448 cleanup);
449
450 r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->eh_policy);
451 goto_if_error(r, "Deserialize policy.", cleanup);
452 }
453
454 if (ifapi_get_sub_object(jso, "sh_policy", &jso2)) {
455 out->sh_policy = calloc(1, sizeof(TPMS_POLICY));
456 goto_if_null2(out->sh_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
457 cleanup);
458
459 r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->sh_policy);
460 goto_if_error(r, "Deserialize policy.", cleanup);
461 }
462
463 if (ifapi_get_sub_object(jso, "ek_policy", &jso2)) {
464 out->ek_policy = calloc(1, sizeof(TPMS_POLICY));
465 goto_if_null2(out->ek_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
466 cleanup);
467
468 r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->ek_policy);
469 goto_if_error(r, "Deserialize policy.", cleanup);
470 }
471
472 if (ifapi_get_sub_object(jso, "srk_policy", &jso2)) {
473 out->srk_policy = calloc(1, sizeof(TPMS_POLICY));
474 goto_if_null2(out->srk_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
475 cleanup);
476
477 r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->srk_policy);
478 goto_if_error(r, "Deserialize policy.", cleanup);
479 }
480
481 if (ifapi_get_sub_object(jso, "lockout_policy", &jso2)) {
482 out->lockout_policy = calloc(1, sizeof(TPMS_POLICY));
483 goto_if_null2(out->lockout_policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
484 cleanup);
485
486 r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->lockout_policy);
487 goto_if_error(r, "Deserialize policy.", cleanup);
488 }
489
490 if (!ifapi_get_sub_object(jso, "newMaxTries", &jso2)) {
491 out->newMaxTries = 5;
492 } else {
493 r = ifapi_json_UINT32_deserialize(jso2, &out->newMaxTries);
494 return_if_error(r, "BAD VALUE");
495 }
496
497 if (!ifapi_get_sub_object(jso, "newRecoveryTime", &jso2)) {
498 out->newRecoveryTime = 1000;
499 } else {
500 r = ifapi_json_UINT32_deserialize(jso2, &out->newRecoveryTime);
501 return_if_error(r, "BAD VALUE");
502 }
503
504 if (!ifapi_get_sub_object(jso, "lockoutRecovery", &jso2)) {
505 out->lockoutRecovery = 1000;
506 } else {
507 r = ifapi_json_UINT32_deserialize(jso2, &out->lockoutRecovery);
508 return_if_error(r, "BAD VALUE");
509 }
510
511 LOG_TRACE("true");
512 return TSS2_RC_SUCCESS;
513
514 cleanup:
515 SAFE_FREE(out->eh_policy);
516 return r;
517 }
518
519 /**
520 * Check whether PCRs with muliple banks are defined in profile.
521 *
522 * This case is not allowed by FAPI.
523 */
524 static TSS2_RC
525 ifapi_profile_checkpcrs(const TPML_PCR_SELECTION *pcr_profile)
526 {
527 size_t i, j, byte_idx;
528
529 for (i = 0; i < pcr_profile->count - 1; i++) {
530 for (j = i + 1; j < pcr_profile->count; j++) {
531 for (byte_idx = 0; byte_idx < 3; byte_idx++) {
532 /* Check whether a PCR register flag does occur in two different banks. */
533 if (pcr_profile->pcrSelections[i].pcrSelect[byte_idx] &
534 pcr_profile->pcrSelections[j].pcrSelect[byte_idx]) {
535 return_error2(TSS2_FAPI_RC_BAD_VALUE,
536 "More than one bank selected for a PCR register.");
537 }
538 }
539 }
540 }
541 return TSS2_RC_SUCCESS;
542 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifndef IFAPI_PROFILES_H
7 #define IFAPI_PROFILES_H
8
9 #include "ifapi_io.h"
10 #include "ifapi_policy_types.h"
11
12 /** Internal structure for FAPI profiles
13 */
14 typedef struct IFAPI_PROFILE {
15 TPMI_ALG_PUBLIC type; /**< The algorithm used for key creation */
16 char *srk_template; /**< name of SRK template */
17 char *ek_template; /**< name of EK template */
18 TPMT_SIG_SCHEME ecc_signing_scheme; /**< < Signing scheme for the ECC key. */
19 TPMT_SIG_SCHEME rsa_signing_scheme; /**< < Signing scheme for the RSA key. */
20 TPMT_RSA_DECRYPT rsa_decrypt_scheme; /**< < Decrypt scheme for the RSA key. */
21 TPMI_ALG_SYM_MODE sym_mode; /**< < Mode for symmectric encryption. */
22 TPMT_SYM_DEF_OBJECT sym_parameters; /**< < Parameters for symmectric encryption. */
23 UINT16 sym_block_size; /**< < Block size for symmectric encryption. */
24 TPML_PCR_SELECTION pcr_selection; /**< < Parameters for symmectric encryption. */
25 TPMI_ALG_HASH nameAlg;
26 TPMI_RSA_KEY_BITS keyBits;
27 UINT32 exponent;
28 TPMI_ECC_CURVE curveID;
29 TPMT_SYM_DEF session_symmetric;
30 TPMS_POLICY *eh_policy;
31 TPMS_POLICY *sh_policy;
32 TPMS_POLICY *ek_policy;
33 TPMS_POLICY *srk_policy;
34 TPMS_POLICY *lockout_policy;
35 UINT32 newMaxTries;
36 UINT32 newRecoveryTime;
37 UINT32 lockoutRecovery;
38 } IFAPI_PROFILE;
39
40 /* An entry for the dictionary of loaded profiles */
41 typedef struct IFAPI_PROFILE_ENTRY {
42 /** Name of a profile */
43 char *name;
44 /** Values for a profile */
45 struct IFAPI_PROFILE profile;
46 } IFAPI_PROFILE_ENTRY;
47
48 typedef struct IFAPI_PROFILES {
49 char *default_name;
50 struct IFAPI_PROFILE default_profile;
51 /* Dictionary of loaded profiles */
52 struct IFAPI_PROFILE_ENTRY *profiles;
53 char **filenames;
54 /* Size of the loaded profiles dictionary */
55 size_t num_profiles;
56 size_t profiles_idx;
57 } IFAPI_PROFILES;
58
59 TSS2_RC
60 ifapi_profiles_initialize_async(
61 IFAPI_PROFILES *profiles,
62 IFAPI_IO *io,
63 const char *profilesdir,
64 const char *defaultprofile);
65
66 TSS2_RC
67 ifapi_profiles_initialize_finish(
68 IFAPI_PROFILES *profiles,
69 IFAPI_IO *io);
70
71 TSS2_RC
72 ifapi_profiles_get(
73 const IFAPI_PROFILES *profiles,
74 const char *name,
75 const IFAPI_PROFILE **profile);
76
77 void
78 ifapi_profiles_finalize(
79 IFAPI_PROFILES *profiles);
80
81 #endif /* IFAPI_OBJECT_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13
14 #include "tpm_json_deserialize.h"
15 #define LOGMODULE fapijson
16 #include "util/log.h"
17 #include "util/aux_util.h"
18
19 /** Strip a prefix from the input
20 *
21 * Strip the provided prefixes from the provided
22 * input string and return the substring.
23 *
24 * @param[in] in The input string to strip the prefix from
25 * @param[in] ... A list of prefixes to string from the input string
26 * @return The prefix cleared substring
27 */
28 static const char *
29 strip_prefix(const char *in, ...)
30 {
31 va_list ap;
32 const char *prefix;
33
34 if (!in)
35 return NULL;
36
37 va_start(ap, in);
38 while ((prefix = va_arg(ap, const char *)) != NULL) {
39 if (strncasecmp(in, prefix, strlen(prefix)) == 0) {
40 in = &in[strlen(prefix)];
41 }
42 }
43 va_end(ap);
44
45 return in;
46 }
47
48 /* Deserialize according to the rules of parenttype and then filter against values
49 provided in the ... list. */
50 #define SUBTYPE_FILTER(type, parenttype, ...) \
51 TSS2_RC r; \
52 type tab[] = { __VA_ARGS__ }; \
53 type v; \
54 r = ifapi_json_ ## parenttype ## _deserialize(jso, &v); \
55 return_if_error(r, "Bad value"); \
56 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) { \
57 if (v == tab[i]) { \
58 *out = v; \
59 return TSS2_RC_SUCCESS; \
60 } \
61 } \
62 LOG_ERROR("Bad sub-value"); \
63 return TSS2_FAPI_RC_BAD_VALUE;
64
65 /** Deserialize a TPMS_EMPTY .
66 *
67 * @param[out] out not used.
68 * @param[in] jso not used.
69 */
70 TSS2_RC
71 ifapi_json_TPMS_EMPTY_deserialize(json_object *jso, TPMS_EMPTY *out)
72 {
73 (void)(out);
74 (void)(jso);
75 LOG_TRACE("call");
76 return TSS2_RC_SUCCESS;
77 }
78
79 /** Convert a byte array in character representation to binary.
80 *
81 * @param[in] hex the character representation of the byte array
82 * @param[in] vlen the maximal length of the binary byte array.
83 * @param[out] val the byte array.
84 * @retval TSS2_RC_SUCCESS if the function call was a success.
85 * @retval TSS2_FAPI_RC_BAD_VALUE if the character representation is too long.
86 */
87 static TSS2_RC
88 ifapi_hex_to_byte_ary(const char hex[], UINT32 vlen, BYTE val[])
89 {
90 UINT32 j;
91
92 if (vlen < strlen(hex) / 2) {
93 LOG_ERROR("Hex string too long. (%zu > %"PRIu32")", strlen(hex) / 2, vlen);
94 return TSS2_FAPI_RC_BAD_VALUE;
95 }
96 for (j = 0; j < vlen
97 && 2 * j < strlen(hex); j++) { //convert hex-Argv to byte array
98 if (!isxdigit(hex[2 * j]) || (!(hex[2 * j + 1] == 0)
99 && !isxdigit(hex[2 * j + 1]))) {
100 LOG_ERROR("Error in value (%i)", j);
101 return TSS2_FAPI_RC_BAD_VALUE;
102 }
103 val[j] = hex[2 * j] < 65 ? hex[2 * j] - 48 :
104 hex[2 * j] < 97 ? hex[2 * j] - 65 + 10 : hex[2 * j] - 97 + 10;
105 val[j] *= 16;
106 if (hex[2 * j + 1] != 0)
107 val[j] += hex[2 * j + 1] < 65 ? hex[2 * j + 1] - 48 :
108 hex[2 * j + 1] < 97 ? hex[2 * j + 1] - 65 + 10 : hex[2 * j + 1] - 97 + 10;
109 }
110 for (; j < vlen; j++) { //Padd with 0
111 val[j] = 0;
112 }
113 return TSS2_RC_SUCCESS;
114 }
115
116 /** Deserialize a json array of bytes.
117 *
118 * @param[in] jso the parent object of the json byte array.
119 * @param[in] max maximal size of the deserialized object.
120 * @param[out] out* Pointer to the deserialized byte array.
121 * @param[out] out_size the length of the deserialized byte array.
122 * @retval TSS2_RC_SUCCESS if the function call was a success.
123 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
124 */
125 TSS2_RC
126 ifapi_json_byte_deserialize(
127 json_object *jso,
128 UINT32 max,
129 BYTE *out,
130 UINT16 *out_size)
131 {
132 TSS2_RC r;
133
134 json_type jso_type = json_object_get_type(jso);
135 if (jso_type == json_type_array) {
136 r = ifapi_json_BYTE_array_deserialize(max, jso, out);
137 return_if_error(r, "BAD VALUE");
138 *out_size = json_object_array_length(jso);
139 } else if (jso_type == json_type_string) {
140 const char *token = json_object_get_string(jso);
141 int itoken = 0;
142 if (strncmp(token, "0x", 2) == 0)
143 itoken = 2;
144 r = ifapi_hex_to_byte_ary(&token[itoken], max, out);
145 *out_size = (strlen(token) - itoken) / 2;
146 return_if_error(r, "Error convert hex digest to binary.");
147 }
148 return TSS2_RC_SUCCESS;
149 }
150
151 /** Get number from a string.
152 *
153 * A string which represents a number or hex number (prefix 0x) is converted
154 * to an int64 number.
155 *
156 * param[in] token the string representing the number.
157 * param[out] num the converted number.
158 * @retval true if token represents a number
159 * @retval false if token does not represent a number.
160 */
161 static bool
162 get_number(const char *token, int64_t *num)
163 {
164 int itoken = 0;
165 int pos = 0;
166 if (strncmp(token, "0x", 2) == 0) {
167 itoken = 2;
168 sscanf(&token[itoken], "%"PRIx64"%n", num, &pos);
169 } else {
170 sscanf(&token[itoken], "%"PRId64"%n", num, &pos);
171 }
172 if ((size_t)pos == strlen(token) - itoken)
173 return true;
174 else
175 return false;
176 }
177
178 /** Get sub object from a json object.
179 *
180 * A sub object with a certain name stored in the passed object is returned.
181 * If the sub object is not found e second trial with the lower case version
182 * of the name will be performed.
183 *
184 * param[in] jso the object with the sub object.
185 * param[in] name the name of the stored sub object.
186 * param[out] sub_jso the pointer to the sub object.
187 * @retval true if object was found.
188 * @retval false if the object was not found.
189 */
190 bool
191 ifapi_get_sub_object(json_object *jso, char *name, json_object **sub_jso)
192 {
193 int i;
194 if (json_object_object_get_ex(jso, name, sub_jso)) {
195 return true;
196 } else {
197 char name2[strlen(name) + 1];
198 for (i = 0; name[i]; i++)
199 name2[i] = tolower(name[i]);
200 name2[strlen(name)] = '\0';
201 return json_object_object_get_ex(jso, name2, sub_jso);
202 }
203 }
204
205 /** Get number from a json object.
206 *
207 * A int64 number is retrieved from a json object which should represent a number.
208 *
209 * param[in] jso the json object.
210 * param[out] num the int64 number.
211 * @retval TSS2_RC_SUCCESS if json object represents a number.
212 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object does not represent a number.
213 */
214 static TSS2_RC
215 get_number_from_json(json_object *jso, int64_t *num)
216 {
217 const char *token = json_object_get_string(jso);
218 if (!get_number(token, num)) {
219 LOG_ERROR("Bad value");
220 return TSS2_FAPI_RC_BAD_VALUE;
221 }
222 return TSS2_RC_SUCCESS;
223 }
224
225 /** Get boolean from a json object.
226 *
227 * A boolean value is retrieved from a json object.
228 * The value can be 1, 0, yes, or no.
229 *
230 * param[in] jso the json object.
231 * param[out] value the boolean value.
232 * @retval TSS2_RC_SUCCESS if json object represents a boolean.
233 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object does not represent a boolean.
234 */
235 static TSS2_RC
236 get_boolean_from_json(json_object *jso, TPMI_YES_NO *value)
237 {
238 TSS2_RC r = ifapi_json_TPMI_YES_NO_deserialize(jso, value);
239 if (r != TSS2_RC_SUCCESS) {
240 const char *token = json_object_get_string(jso);
241 if (strcasecmp(token, "set") || strcasecmp(token, "on")) {
242 *value = 1;
243 } else if (strcasecmp(token, "off")) {
244 *value = 0;
245 } else {
246 return_error(TSS2_FAPI_RC_BAD_VALUE, "No boolean value");
247 }
248 }
249 if (*value != 0 && *value != 1) {
250 return_error(TSS2_FAPI_RC_BAD_VALUE, "No boolean value.");
251 };
252 return TSS2_RC_SUCCESS;
253 }
254
255 /** Deserialize json object which represents a pcr selection.
256 *
257 * @param[in] jso json array of pcr registers.
258 * @param[out] sizeofSelect size of bit mask for used pcr registers.
259 * @param[out] pcrSelect byte array with bit mask.
260 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
261 * the function.
262 */
263 TSS2_RC
264 ifapi_json_pcr_selection_deserialize(
265 json_object *jso,
266 UINT8 *sizeofSelect,
267 BYTE pcrSelect[])
268 {
269 LOG_TRACE("call");
270 TSS2_RC r;
271 size_t i;
272 int64_t n;
273 int n_byte = 0;
274 json_type jso_type = json_object_get_type(jso);
275
276 if (jso_type != json_type_array) {
277 return_error(TSS2_FAPI_RC_BAD_VALUE, "Bad value (array of numbers expected).");
278 }
279 /* Cast (size_t) is necessary to support older version of libjson-c */
280 for (i = 0; i < (size_t)json_object_array_length(jso); i++) {
281 r = get_number_from_json(json_object_array_get_idx(jso, i), &n);
282 return_if_error(r, "Bad PCR value");
283 n_byte = n / 8;
284 pcrSelect[n_byte] |= (BYTE)(1 << (n % 8));
285 if (n_byte > *sizeofSelect)
286 *sizeofSelect = n_byte;
287 }
288 *sizeofSelect = 3;
289 return TSS2_RC_SUCCESS;
290 }
291
292 /** Deserialize an array of UINT8.
293 *
294 * @param[in] jso object to be deserialized.
295 * @param[out] out the deserialized object.
296 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
297 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
298 * the function.
299 */
300 TSS2_RC
301 ifapi_json_UINT8_ARY_deserialize(
302 json_object *jso,
303 UINT8_ARY *out)
304 {
305 TSS2_RC r;
306
307 const char *hex_string = json_object_get_string(jso);
308 out->size = strlen(hex_string) / 2;
309 out->buffer = malloc(out->size);
310 return_if_null(out->buffer, "Out of memory.", TSS2_FAPI_RC_MEMORY);
311
312 r = ifapi_hex_to_byte_ary(hex_string, out->size, &out->buffer[0]);
313 return_if_error(r, "Can't convert hex values.");
314
315 return TSS2_RC_SUCCESS;
316 }
317
318 /** Deserialize a TPMS_PCR_SELECT variable.
319 *
320 * @param[in] jso json object to be deserialized.
321 * @param[out] out the deserialized object.
322 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
323 * the function.
324 */
325 TSS2_RC
326 ifapi_json_TPMS_PCR_SELECT_deserialize(json_object *jso, TPMS_PCR_SELECT *out)
327 {
328 LOG_TRACE("call");
329
330 memset(out, 0, sizeof(TPMS_PCR_SELECT));
331 return ifapi_json_pcr_selection_deserialize(jso, &out->sizeofSelect,
332 &out->pcrSelect[0]);
333 }
334
335 /** Deserialize a TPMS_PCR_SELECTION variable.
336 *
337 * @param[in] jso json object to be deserialized.
338 * @param[out] out the deserialized object.
339 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
340 * the function.
341 */
342 TSS2_RC
343 ifapi_json_TPMS_PCR_SELECTION_deserialize(json_object *jso,
344 TPMS_PCR_SELECTION *out)
345 {
346 LOG_TRACE("call");
347 json_object *jso2;
348 TSS2_RC r;
349
350 memset(out, 0, sizeof(TPMS_PCR_SELECTION));
351 if (!ifapi_get_sub_object(jso, "hash", &jso2)) {
352 LOG_ERROR("Bad value");
353 return TSS2_FAPI_RC_BAD_VALUE;
354 }
355 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->hash);
356 return_if_error(r, "BAD VALUE");
357
358 if (!ifapi_get_sub_object(jso, "pcrSelect", &jso2)) {
359 LOG_ERROR("Bad value");
360 return TSS2_FAPI_RC_BAD_VALUE;
361 }
362 return ifapi_json_pcr_selection_deserialize(jso2, &out->sizeofSelect,
363 &out->pcrSelect[0]);
364 }
365
366 /** Deserialize an array of BYTE structures.
367 *
368 * @param[in] max the maximal number of bytess to be deserialized.
369 * @param[in] jso the JSON object with the byte array.
370 * @param[in] out the byte array for deserialization.
371 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
372 * the function.
373 */
374 TSS2_RC
375 ifapi_json_BYTE_array_deserialize(size_t max, json_object *jso, BYTE *out)
376 {
377 LOG_TRACE("call");
378 json_type jso_type = json_object_get_type(jso);
379 if (jso_type == json_type_array) {
380 int size = json_object_array_length(jso);
381 if (size > (int)max) {
382 LOG_ERROR("Array of BYTE too large (%i > %zu)", size, max);
383 }
384 for (int i = 0; i < size; i++) {
385 json_object *jso2 = json_object_array_get_idx(jso, i);
386 TSS2_RC r = ifapi_json_BYTE_deserialize(jso2, &out[i]);
387 return_if_error(r, "BAD VALUE");
388 }
389 return TSS2_RC_SUCCESS;
390 } else {
391 LOG_ERROR("BAD VALUE");
392 return TSS2_FAPI_RC_BAD_VALUE;
393 }
394 }
395
396 /** Deserialize a BYTE json object.
397 *
398 * @param[in] jso the json object to be deserialized.
399 * @param[out] out the deserialzed binary object.
400 * @retval TSS2_RC_SUCCESS if the function call was a success.
401 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
402 */
403 TSS2_RC
404 ifapi_json_BYTE_deserialize(json_object *jso, BYTE *out)
405 {
406 LOG_TRACE("call");
407 const char *token = json_object_get_string(jso);
408 int64_t i64;
409 if (!get_number(token, &i64)) {
410 LOG_ERROR("Bad value");
411 return TSS2_FAPI_RC_BAD_VALUE;
412 }
413 *out = (BYTE) i64;
414 if ((int64_t)*out != i64) {
415 LOG_ERROR("Bad value");
416 return TSS2_FAPI_RC_BAD_VALUE;
417 }
418 return TSS2_RC_SUCCESS;
419 }
420
421 /** Deserialize a UINT8 json object.
422 *
423 * @param[in] jso the json object to be deserialized.
424 * @param[out] out the deserialzed binary object.
425 * @retval TSS2_RC_SUCCESS if the function call was a success.
426 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
427 */
428 TSS2_RC
429 ifapi_json_UINT8_deserialize(json_object *jso, UINT8 *out)
430 {
431 LOG_TRACE("call");
432 const char *token = json_object_get_string(jso);
433 int64_t i64;
434 if (!get_number(token, &i64)) {
435 LOG_ERROR("Bad value");
436 return TSS2_FAPI_RC_BAD_VALUE;
437 }
438 *out = (UINT8) i64;
439 if ((int64_t)*out != i64) {
440 LOG_ERROR("Bad value");
441 return TSS2_FAPI_RC_BAD_VALUE;
442 }
443 return TSS2_RC_SUCCESS;
444 }
445
446 /** Deserialize a UINT16 json object.
447 *
448 * @param[in] jso the json object to be deserialized.
449 * @param[out] out the deserialzed binary object.
450 * @retval TSS2_RC_SUCCESS if the function call was a success.
451 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
452 */
453 TSS2_RC
454 ifapi_json_UINT16_deserialize(json_object *jso, UINT16 *out)
455 {
456 LOG_TRACE("call");
457 const char *token = json_object_get_string(jso);
458 int64_t i64;
459 if (!get_number(token, &i64)) {
460 LOG_ERROR("Bad value %s", json_object_get_string(jso));
461 return TSS2_FAPI_RC_BAD_VALUE;
462 }
463 *out = (UINT16) i64;
464 if ((int64_t)*out != i64) {
465 LOG_ERROR("Bad value %s", json_object_get_string(jso));
466 return TSS2_FAPI_RC_BAD_VALUE;
467 }
468 return TSS2_RC_SUCCESS;
469 }
470
471 /** Deserialize a UINT32 json object.
472 *
473 * @param[in] jso the json object to be deserialized.
474 * @param[out] out the deserialzed binary object.
475 * @retval TSS2_RC_SUCCESS if the function call was a success.
476 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
477 */
478 TSS2_RC
479 ifapi_json_UINT32_deserialize(json_object *jso, UINT32 *out)
480 {
481 LOG_TRACE("call");
482 const char *token = json_object_get_string(jso);
483 int64_t i64;
484 if (!get_number(token, &i64)) {
485 LOG_ERROR("Bad value");
486 return TSS2_FAPI_RC_BAD_VALUE;
487 }
488 *out = (UINT32) i64;
489 if ((int64_t)*out != i64) {
490 LOG_ERROR("Bad value");
491 return TSS2_FAPI_RC_BAD_VALUE;
492 }
493 return TSS2_RC_SUCCESS;
494 }
495
496 /** Deserialize a UINT64 json object.
497 *
498 * @param[in] jso the json object to be deserialized.
499 * @param[out] out the deserialzed binary object.
500 * @retval TSS2_RC_SUCCESS if the function call was a success.
501 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
502 */
503 TSS2_RC
504 ifapi_json_UINT64_deserialize(json_object *jso, UINT64 *out)
505 {
506 UINT32 tmp;
507 LOG_TRACE("call");
508 /* json-c allows only 53 bit numbers, therefore 64 bit numbers are split */
509 if (json_object_get_type(jso) == json_type_array) {
510 if (json_object_array_length(jso) != 2) {
511 LOG_ERROR("Bad value");
512 return TSS2_FAPI_RC_BAD_VALUE;
513 }
514 TSS2_RC r = ifapi_json_UINT32_deserialize(json_object_array_get_idx(jso, 0),
515 &tmp);
516 return_if_error(r, "BAD VALUE");
517 *out = tmp * 0x100000000;
518
519 r = ifapi_json_UINT32_deserialize(json_object_array_get_idx(jso, 1),
520 &tmp);
521 return_if_error(r, "BAD VALUE");
522 *out += tmp;
523 return TSS2_RC_SUCCESS;
524 }
525
526 const char *token = json_object_get_string(jso);
527 int64_t i64;
528 if (!get_number(token, &i64)) {
529 LOG_ERROR("Bad value");
530 return TSS2_FAPI_RC_BAD_VALUE;
531 }
532 *out = (UINT64) i64;
533 if ((int64_t)*out != i64) {
534 LOG_ERROR("Bad value");
535 return TSS2_FAPI_RC_BAD_VALUE;
536 }
537 return TSS2_RC_SUCCESS;
538 }
539
540 /** Deserialize a TPM2_GENERATED json object.
541 *
542 * @param[in] jso the json object to be deserialized.
543 * @param[out] out the deserialzed binary object.
544 * @retval TSS2_RC_SUCCESS if the function call was a success.
545 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
546 */
547 TSS2_RC
548 ifapi_json_TPM2_GENERATED_deserialize(json_object *jso, TPM2_GENERATED *out)
549 {
550 static const struct { TPM2_GENERATED in; const char *name; } tab[] = {
551 { TPM2_GENERATED_VALUE, "VALUE" },
552 };
553
554 const char *s = json_object_get_string(jso);
555 const char *str = strip_prefix(s, "TPM_", "TPM2_", "GENERATED_", NULL);
556 LOG_TRACE("called for %s parsing %s", s, str);
557
558 if (str) {
559 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
560 if (strcasecmp(str, &tab[i].name[0]) == 0) {
561 *out = tab[i].in;
562 return TSS2_RC_SUCCESS;
563 }
564 }
565 }
566
567 return ifapi_json_UINT32_deserialize(jso, out);
568 }
569
570 /** Deserialize a TPM2_ALG_ID json object.
571 *
572 * @param[in] jso the json object to be deserialized.
573 * @param[out] out the deserialzed binary object.
574 * @retval TSS2_RC_SUCCESS if the function call was a success.
575 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
576 */
577 TSS2_RC
578 ifapi_json_TPM2_ALG_ID_deserialize(json_object *jso, TPM2_ALG_ID *out)
579 {
580 static const struct { TPM2_ALG_ID in; const char *name; } tab[] = {
581 { TPM2_ALG_ERROR, "ERROR" },
582 { TPM2_ALG_RSA, "RSA" },
583 { TPM2_ALG_SHA, "SHA" },
584 { TPM2_ALG_SHA1, "SHA1" },
585 { TPM2_ALG_HMAC, "HMAC" },
586 { TPM2_ALG_AES, "AES" },
587 { TPM2_ALG_MGF1, "MGF1" },
588 { TPM2_ALG_KEYEDHASH, "KEYEDHASH" },
589 { TPM2_ALG_XOR, "XOR" },
590 { TPM2_ALG_SHA256, "SHA256" },
591 { TPM2_ALG_SHA384, "SHA384" },
592 { TPM2_ALG_SHA512, "SHA512" },
593 { TPM2_ALG_NULL, "NULL" },
594 { TPM2_ALG_SM3_256, "SM3_256" },
595 { TPM2_ALG_SM4, "SM4" },
596 { TPM2_ALG_RSASSA, "RSASSA" },
597 { TPM2_ALG_RSAES, "RSAES" },
598 { TPM2_ALG_RSAPSS, "RSAPSS" },
599 { TPM2_ALG_OAEP, "OAEP" },
600 { TPM2_ALG_ECDSA, "ECDSA" },
601 { TPM2_ALG_ECDH, "ECDH" },
602 { TPM2_ALG_ECDAA, "ECDAA" },
603 { TPM2_ALG_SM2, "SM2" },
604 { TPM2_ALG_ECSCHNORR, "ECSCHNORR" },
605 { TPM2_ALG_ECMQV, "ECMQV" },
606 { TPM2_ALG_KDF1_SP800_56A, "KDF1_SP800_56A" },
607 { TPM2_ALG_KDF2, "KDF2" },
608 { TPM2_ALG_KDF1_SP800_108, "KDF1_SP800_108" },
609 { TPM2_ALG_ECC, "ECC" },
610 { TPM2_ALG_SYMCIPHER, "SYMCIPHER" },
611 { TPM2_ALG_CAMELLIA, "CAMELLIA" },
612 { TPM2_ALG_CTR, "CTR" },
613 { TPM2_ALG_OFB, "OFB" },
614 { TPM2_ALG_CBC, "CBC" },
615 { TPM2_ALG_CFB, "CFB" },
616 { TPM2_ALG_ECB, "ECB" },
617 };
618
619 const char *s = json_object_get_string(jso);
620 const char *str = strip_prefix(s, "TPM_", "TPM2_", "ALG_", "ID_", NULL);
621 LOG_TRACE("called for %s parsing %s", s, str);
622
623 if (str) {
624 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
625 if (strcasecmp(str, &tab[i].name[0]) == 0) {
626 *out = tab[i].in;
627 return TSS2_RC_SUCCESS;
628 }
629 }
630 }
631
632 return ifapi_json_UINT16_deserialize(jso, out);
633 }
634
635 /** Deserialize a TPM2_ECC_CURVE json object.
636 *
637 * @param[in] jso the json object to be deserialized.
638 * @param[out] out the deserialzed binary object.
639 * @retval TSS2_RC_SUCCESS if the function call was a success.
640 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
641 */
642 TSS2_RC
643 ifapi_json_TPM2_ECC_CURVE_deserialize(json_object *jso, TPM2_ECC_CURVE *out)
644 {
645 static const struct { TPM2_ECC_CURVE in; const char *name; } tab[] = {
646 { TPM2_ECC_NONE, "NONE" },
647 { TPM2_ECC_NIST_P192, "NIST_P192" },
648 { TPM2_ECC_NIST_P224, "NIST_P224" },
649 { TPM2_ECC_NIST_P256, "NIST_P256" },
650 { TPM2_ECC_NIST_P384, "NIST_P384" },
651 { TPM2_ECC_NIST_P521, "NIST_P521" },
652 { TPM2_ECC_BN_P256, "BN_P256" },
653 { TPM2_ECC_BN_P638, "BN_P638" },
654 { TPM2_ECC_SM2_P256, "SM2_P256" },
655 };
656
657 const char *s = json_object_get_string(jso);
658 const char *str = strip_prefix(s, "TPM_", "TPM2_", "ECC_", "CURVE_", NULL);
659 LOG_TRACE("called for %s parsing %s", s, str);
660
661 if (str) {
662 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
663 if (strcasecmp(str, &tab[i].name[0]) == 0) {
664 *out = tab[i].in;
665 return TSS2_RC_SUCCESS;
666 }
667 }
668 }
669
670 return ifapi_json_UINT16_deserialize(jso, out);
671 }
672
673 /** Deserialize a TPM2_CC json object.
674 *
675 * @param[in] jso the json object to be deserialized.
676 * @param[out] out the deserialzed binary object.
677 * @retval TSS2_RC_SUCCESS if the function call was a success.
678 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
679 */
680 TSS2_RC
681 ifapi_json_TPM2_CC_deserialize(json_object *jso, TPM2_CC *out)
682 {
683 static const struct { TPM2_CC in; const char *name; } tab[] = {
684 { TPM2_CC_FIRST, "FIRST" },
685 { TPM2_CC_NV_UndefineSpaceSpecial, "NV_UndefineSpaceSpecial" },
686 { TPM2_CC_EvictControl, "EvictControl" },
687 { TPM2_CC_HierarchyControl, "HierarchyControl" },
688 { TPM2_CC_NV_UndefineSpace, "NV_UndefineSpace" },
689 { TPM2_CC_ChangeEPS, "ChangeEPS" },
690 { TPM2_CC_ChangePPS, "ChangePPS" },
691 { TPM2_CC_Clear, "Clear" },
692 { TPM2_CC_ClearControl, "ClearControl" },
693 { TPM2_CC_ClockSet, "ClockSet" },
694 { TPM2_CC_HierarchyChangeAuth, "HierarchyChangeAuth" },
695 { TPM2_CC_NV_DefineSpace, "NV_DefineSpace" },
696 { TPM2_CC_PCR_Allocate, "PCR_Allocate" },
697 { TPM2_CC_PCR_SetAuthPolicy, "PCR_SetAuthPolicy" },
698 { TPM2_CC_PP_Commands, "PP_Commands" },
699 { TPM2_CC_SetPrimaryPolicy, "SetPrimaryPolicy" },
700 { TPM2_CC_FieldUpgradeStart, "FieldUpgradeStart" },
701 { TPM2_CC_ClockRateAdjust, "ClockRateAdjust" },
702 { TPM2_CC_CreatePrimary, "CreatePrimary" },
703 { TPM2_CC_NV_GlobalWriteLock, "NV_GlobalWriteLock" },
704 { TPM2_CC_GetCommandAuditDigest, "GetCommandAuditDigest" },
705 { TPM2_CC_NV_Increment, "NV_Increment" },
706 { TPM2_CC_NV_SetBits, "NV_SetBits" },
707 { TPM2_CC_NV_Extend, "NV_Extend" },
708 { TPM2_CC_NV_Write, "NV_Write" },
709 { TPM2_CC_NV_WriteLock, "NV_WriteLock" },
710 { TPM2_CC_DictionaryAttackLockReset, "DictionaryAttackLockReset" },
711 { TPM2_CC_DictionaryAttackParameters, "DictionaryAttackParameters" },
712 { TPM2_CC_NV_ChangeAuth, "NV_ChangeAuth" },
713 { TPM2_CC_PCR_Event, "PCR_Event" },
714 { TPM2_CC_PCR_Reset, "PCR_Reset" },
715 { TPM2_CC_SequenceComplete, "SequenceComplete" },
716 { TPM2_CC_SetAlgorithmSet, "SetAlgorithmSet" },
717 { TPM2_CC_SetCommandCodeAuditStatus, "SetCommandCodeAuditStatus" },
718 { TPM2_CC_FieldUpgradeData, "FieldUpgradeData" },
719 { TPM2_CC_IncrementalSelfTest, "IncrementalSelfTest" },
720 { TPM2_CC_SelfTest, "SelfTest" },
721 { TPM2_CC_Startup, "Startup" },
722 { TPM2_CC_Shutdown, "Shutdown" },
723 { TPM2_CC_StirRandom, "StirRandom" },
724 { TPM2_CC_ActivateCredential, "ActivateCredential" },
725 { TPM2_CC_Certify, "Certify" },
726 { TPM2_CC_PolicyNV, "PolicyNV" },
727 { TPM2_CC_CertifyCreation, "CertifyCreation" },
728 { TPM2_CC_Duplicate, "Duplicate" },
729 { TPM2_CC_GetTime, "GetTime" },
730 { TPM2_CC_GetSessionAuditDigest, "GetSessionAuditDigest" },
731 { TPM2_CC_NV_Read, "NV_Read" },
732 { TPM2_CC_NV_ReadLock, "NV_ReadLock" },
733 { TPM2_CC_ObjectChangeAuth, "ObjectChangeAuth" },
734 { TPM2_CC_PolicySecret, "PolicySecret" },
735 { TPM2_CC_Rewrap, "Rewrap" },
736 { TPM2_CC_Create, "Create" },
737 { TPM2_CC_ECDH_ZGen, "ECDH_ZGen" },
738 { TPM2_CC_HMAC, "HMAC" },
739 { TPM2_CC_Import, "Import" },
740 { TPM2_CC_Load, "Load" },
741 { TPM2_CC_Quote, "Quote" },
742 { TPM2_CC_RSA_Decrypt, "RSA_Decrypt" },
743 { TPM2_CC_HMAC_Start, "HMAC_Start" },
744 { TPM2_CC_SequenceUpdate, "SequenceUpdate" },
745 { TPM2_CC_Sign, "Sign" },
746 { TPM2_CC_Unseal, "Unseal" },
747 { TPM2_CC_PolicySigned, "PolicySigned" },
748 { TPM2_CC_ContextLoad, "ContextLoad" },
749 { TPM2_CC_ContextSave, "ContextSave" },
750 { TPM2_CC_ECDH_KeyGen, "ECDH_KeyGen" },
751 { TPM2_CC_EncryptDecrypt, "EncryptDecrypt" },
752 { TPM2_CC_FlushContext, "FlushContext" },
753 { TPM2_CC_LoadExternal, "LoadExternal" },
754 { TPM2_CC_MakeCredential, "MakeCredential" },
755 { TPM2_CC_NV_ReadPublic, "NV_ReadPublic" },
756 { TPM2_CC_PolicyAuthorize, "PolicyAuthorize" },
757 { TPM2_CC_PolicyAuthValue, "PolicyAuthValue" },
758 { TPM2_CC_PolicyCommandCode, "PolicyCommandCode" },
759 { TPM2_CC_PolicyCounterTimer, "PolicyCounterTimer" },
760 { TPM2_CC_PolicyCpHash, "PolicyCpHash" },
761 { TPM2_CC_PolicyLocality, "PolicyLocality" },
762 { TPM2_CC_PolicyNameHash, "PolicyNameHash" },
763 { TPM2_CC_PolicyOR, "PolicyOR" },
764 { TPM2_CC_PolicyTicket, "PolicyTicket" },
765 { TPM2_CC_ReadPublic, "ReadPublic" },
766 { TPM2_CC_RSA_Encrypt, "RSA_Encrypt" },
767 { TPM2_CC_StartAuthSession, "StartAuthSession" },
768 { TPM2_CC_VerifySignature, "VerifySignature" },
769 { TPM2_CC_ECC_Parameters, "ECC_Parameters" },
770 { TPM2_CC_FirmwareRead, "FirmwareRead" },
771 { TPM2_CC_GetCapability, "GetCapability" },
772 { TPM2_CC_GetRandom, "GetRandom" },
773 { TPM2_CC_GetTestResult, "GetTestResult" },
774 { TPM2_CC_Hash, "Hash" },
775 { TPM2_CC_PCR_Read, "PCR_Read" },
776 { TPM2_CC_PolicyPCR, "PolicyPCR" },
777 { TPM2_CC_PolicyRestart, "PolicyRestart" },
778 { TPM2_CC_ReadClock, "ReadClock" },
779 { TPM2_CC_PCR_Extend, "PCR_Extend" },
780 { TPM2_CC_PCR_SetAuthValue, "PCR_SetAuthValue" },
781 { TPM2_CC_NV_Certify, "NV_Certify" },
782 { TPM2_CC_EventSequenceComplete, "EventSequenceComplete" },
783 { TPM2_CC_HashSequenceStart, "HashSequenceStart" },
784 { TPM2_CC_PolicyPhysicalPresence, "PolicyPhysicalPresence" },
785 { TPM2_CC_PolicyDuplicationSelect, "PolicyDuplicationSelect" },
786 { TPM2_CC_PolicyGetDigest, "PolicyGetDigest" },
787 { TPM2_CC_TestParms, "TestParms" },
788 { TPM2_CC_Commit, "Commit" },
789 { TPM2_CC_PolicyPassword, "PolicyPassword" },
790 { TPM2_CC_ZGen_2Phase, "ZGen_2Phase" },
791 { TPM2_CC_EC_Ephemeral, "EC_Ephemeral" },
792 { TPM2_CC_PolicyNvWritten, "PolicyNvWritten" },
793 { TPM2_CC_PolicyTemplate, "PolicyTemplate" },
794 { TPM2_CC_CreateLoaded, "CreateLoaded" },
795 { TPM2_CC_PolicyAuthorizeNV, "PolicyAuthorizeNV" },
796 { TPM2_CC_EncryptDecrypt2, "EncryptDecrypt2" },
797 { TPM2_CC_LAST, "LAST" },
798 { TPM2_CC_Vendor_TCG_Test, "Vendor_TCG_Test" },
799 };
800
801 const char *s = json_object_get_string(jso);
802 const char *str = strip_prefix(s, "TPM_", "TPM2_", "CC_", NULL);
803 LOG_TRACE("called for %s parsing %s", s, str);
804
805 if (str) {
806 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
807 if (strcasecmp(str, &tab[i].name[0]) == 0) {
808 *out = tab[i].in;
809 return TSS2_RC_SUCCESS;
810 }
811 }
812 }
813
814 return ifapi_json_UINT32_deserialize(jso, out);
815 }
816
817 /** Deserialize a TPM2_EO json object.
818 *
819 * @param[in] jso the json object to be deserialized.
820 * @param[out] out the deserialzed binary object.
821 * @retval TSS2_RC_SUCCESS if the function call was a success.
822 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
823 */
824 TSS2_RC
825 ifapi_json_TPM2_EO_deserialize(json_object *jso, TPM2_EO *out)
826 {
827 static const struct { TPM2_EO in; const char *name; } tab[] = {
828 { TPM2_EO_EQ, "EQ" },
829 { TPM2_EO_NEQ, "NEQ" },
830 { TPM2_EO_SIGNED_GT, "SIGNED_GT" },
831 { TPM2_EO_UNSIGNED_GT, "UNSIGNED_GT" },
832 { TPM2_EO_SIGNED_LT, "SIGNED_LT" },
833 { TPM2_EO_UNSIGNED_LT, "UNSIGNED_LT" },
834 { TPM2_EO_SIGNED_GE, "SIGNED_GE" },
835 { TPM2_EO_UNSIGNED_GE, "UNSIGNED_GE" },
836 { TPM2_EO_SIGNED_LE, "SIGNED_LE" },
837 { TPM2_EO_UNSIGNED_LE, "UNSIGNED_LE" },
838 { TPM2_EO_BITSET, "BITSET" },
839 { TPM2_EO_BITCLEAR, "BITCLEAR" },
840 };
841
842 const char *s = json_object_get_string(jso);
843 const char *str = strip_prefix(s, "TPM_", "TPM2_", "EO_", NULL);
844 LOG_TRACE("called for %s parsing %s", s, str);
845
846 if (str) {
847 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
848 if (strcasecmp(str, &tab[i].name[0]) == 0) {
849 *out = tab[i].in;
850 return TSS2_RC_SUCCESS;
851 }
852 }
853 }
854
855 return ifapi_json_UINT16_deserialize(jso, out);
856 }
857
858 /** Deserialize a TPM2_ST json object.
859 *
860 * @param[in] jso the json object to be deserialized.
861 * @param[out] out the deserialzed binary object.
862 * @retval TSS2_RC_SUCCESS if the function call was a success.
863 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
864 */
865 TSS2_RC
866 ifapi_json_TPM2_ST_deserialize(json_object *jso, TPM2_ST *out)
867 {
868 static const struct { TPM2_ST in; const char *name; } tab[] = {
869 { TPM2_ST_RSP_COMMAND, "RSP_COMMAND" },
870 { TPM2_ST_NULL, "NULL" },
871 { TPM2_ST_NO_SESSIONS, "NO_SESSIONS" },
872 { TPM2_ST_SESSIONS, "SESSIONS" },
873 { TPM2_ST_ATTEST_NV, "ATTEST_NV" },
874 { TPM2_ST_ATTEST_COMMAND_AUDIT, "ATTEST_COMMAND_AUDIT" },
875 { TPM2_ST_ATTEST_SESSION_AUDIT, "ATTEST_SESSION_AUDIT" },
876 { TPM2_ST_ATTEST_CERTIFY, "ATTEST_CERTIFY" },
877 { TPM2_ST_ATTEST_QUOTE, "ATTEST_QUOTE" },
878 { TPM2_ST_ATTEST_TIME, "ATTEST_TIME" },
879 { TPM2_ST_ATTEST_CREATION, "ATTEST_CREATION" },
880 { TPM2_ST_CREATION, "CREATION" },
881 { TPM2_ST_VERIFIED, "VERIFIED" },
882 { TPM2_ST_AUTH_SECRET, "AUTH_SECRET" },
883 { TPM2_ST_HASHCHECK, "HASHCHECK" },
884 { TPM2_ST_AUTH_SIGNED, "AUTH_SIGNED" },
885 { TPM2_ST_FU_MANIFEST, "FU_MANIFEST" },
886 };
887
888 const char *s = json_object_get_string(jso);
889 const char *str = strip_prefix(s, "TPM_", "TPM2_", "ST_", NULL);
890 LOG_TRACE("called for %s parsing %s", s, str);
891
892 if (str) {
893 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
894 if (strcasecmp(str, &tab[i].name[0]) == 0) {
895 *out = tab[i].in;
896 return TSS2_RC_SUCCESS;
897 }
898 }
899 }
900
901 return ifapi_json_UINT16_deserialize(jso, out);
902 }
903
904 /** Deserialize a TPM2_PT_PCR json object.
905 *
906 * @param[in] jso the json object to be deserialized.
907 * @param[out] out the deserialzed binary object.
908 * @retval TSS2_RC_SUCCESS if the function call was a success.
909 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
910 */
911 TSS2_RC
912 ifapi_json_TPM2_PT_PCR_deserialize(json_object *jso, TPM2_PT_PCR *out)
913 {
914 static const struct { TPM2_PT_PCR in; const char *name; } tab[] = {
915 { TPM2_PT_TPM2_PCR_FIRST, "FIRST" },
916 { TPM2_PT_PCR_SAVE, "SAVE" },
917 { TPM2_PT_PCR_EXTEND_L0, "EXTEND_L0" },
918 { TPM2_PT_PCR_RESET_L0, "RESET_L0" },
919 { TPM2_PT_PCR_EXTEND_L1, "EXTEND_L1" },
920 { TPM2_PT_PCR_RESET_L1, "RESET_L1" },
921 { TPM2_PT_PCR_EXTEND_L2, "EXTEND_L2" },
922 { TPM2_PT_PCR_RESET_L2, "RESET_L2" },
923 { TPM2_PT_PCR_EXTEND_L3, "EXTEND_L3" },
924 { TPM2_PT_PCR_RESET_L3, "RESET_L3" },
925 { TPM2_PT_PCR_EXTEND_L4, "EXTEND_L4" },
926 { TPM2_PT_PCR_RESET_L4, "RESET_L4" },
927 { TPM2_PT_PCR_NO_INCREMENT, "NO_INCREMENT" },
928 { TPM2_PT_PCR_DRTM_RESET, "DRTM_RESET" },
929 { TPM2_PT_PCR_POLICY, "POLICY" },
930 { TPM2_PT_PCR_AUTH, "AUTH" },
931 { TPM2_PT_TPM2_PCR_LAST, "LAST" }
932 };
933
934 const char *s = json_object_get_string(jso);
935 const char *str = strip_prefix(s, "TPM_", "TPM2_", "PT_", "PCR_", NULL);
936 LOG_TRACE("called for %s parsing %s", s, str);
937
938 if (str) {
939 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
940 if (strcasecmp(str, &tab[i].name[0]) == 0) {
941 *out = tab[i].in;
942 return TSS2_RC_SUCCESS;
943 }
944 }
945 }
946
947 return ifapi_json_UINT32_deserialize(jso, out);
948 }
949
950 /*** Table 26 .Definition of Types for HandlesTable ***/
951
952 /** Deserialize a TPM2_HANDLE json object.
953 *
954 * @param[in] jso the json object to be deserialized.
955 * @param[out] out the deserialzed binary object.
956 * @retval TSS2_RC_SUCCESS if the function call was a success.
957 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
958 */
959 TSS2_RC
960 ifapi_json_TPM2_HANDLE_deserialize(json_object *jso, TPM2_HANDLE *out)
961 {
962 LOG_TRACE("call");
963 const char *token = json_object_get_string(jso);
964 int64_t i64;
965 if (get_number(token, &i64)) {
966 *out = (TPM2_HANDLE) i64;
967 if ((int64_t)*out != i64) {
968 LOG_ERROR("Bad value");
969 return TSS2_FAPI_RC_BAD_VALUE;
970 }
971 return TSS2_RC_SUCCESS;
972 } else {
973 LOG_ERROR("Bad value");
974 return TSS2_FAPI_RC_BAD_VALUE;
975 }
976 }
977
978 /** Deserialize a TPMA_OBJECT json object.
979 *
980 * @param[in] jso the json object to be deserialized.
981 * @param[out] out the deserialzed binary object.
982 * @retval TSS2_RC_SUCCESS if the function call was a success.
983 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
984 */
985 TSS2_RC
986 ifapi_json_TPMA_OBJECT_deserialize(json_object *jso, TPMA_OBJECT *out)
987 {
988 struct { TPMA_OBJECT in; char *name; } tab[] = {
989 { TPMA_OBJECT_FIXEDTPM, "fixedTPM" },
990 { TPMA_OBJECT_STCLEAR, "stClear" },
991 { TPMA_OBJECT_FIXEDPARENT, "fixedParent" },
992 { TPMA_OBJECT_SENSITIVEDATAORIGIN, "sensitiveDataOrigin" },
993 { TPMA_OBJECT_USERWITHAUTH, "userWithAuth" },
994 { TPMA_OBJECT_ADMINWITHPOLICY, "adminWithPolicy" },
995 { TPMA_OBJECT_NODA, "noDA" },
996 { TPMA_OBJECT_ENCRYPTEDDUPLICATION, "encryptedDuplication" },
997 { TPMA_OBJECT_RESTRICTED, "restricted" },
998 { TPMA_OBJECT_DECRYPT, "decrypt" },
999 { TPMA_OBJECT_SIGN_ENCRYPT, "sign" },
1000 };
1001 size_t n = sizeof(tab) / sizeof(tab[0]);
1002 size_t i, j;
1003
1004 TPMI_YES_NO flag;
1005 TSS2_RC r;
1006
1007 LOG_TRACE("call");
1008 memset(out, 0, sizeof(TPMA_OBJECT));
1009 json_type jso_type = json_object_get_type(jso);
1010 if (jso_type == json_type_array) {
1011 /* Cast (size_t) is necessary to support older version of libjson-c */
1012 for (i = 0; i < (size_t)json_object_array_length(jso); i++) {
1013 json_object *jso2 = json_object_array_get_idx(jso, i);
1014 const char *token = strip_prefix(json_object_get_string(jso2),
1015 "TPM_", "TPM2_", "TPMA_", "OBJECT_", NULL);
1016 if (!token) {
1017 LOG_ERROR("Bad object; expected array of strings.");
1018 return TSS2_FAPI_RC_BAD_VALUE;
1019 }
1020 for (j = 0; j < n; j++) {
1021 if (strcasecmp(tab[j].name, token) == 0) {
1022 *out |= tab[j].in;
1023 break;
1024 }
1025 }
1026 if (j == n) {
1027 LOG_ERROR("Unknown value: %s", json_object_get_string(jso2));
1028 return TSS2_FAPI_RC_BAD_VALUE;
1029 }
1030 }
1031 } else if (jso_type == json_type_object) {
1032 json_object_object_foreach(jso, key, val) {
1033 const char *token = strip_prefix(key,
1034 "TPM_", "TPM2_", "TPMA_", "OBJECT_", NULL);
1035 r = get_boolean_from_json(val, &flag);
1036 return_if_error2(r, "Boolean value expected at key: %s", key);
1037 for (j = 0; j < n; j++) {
1038 if (strcasecmp(tab[j].name, token) == 0) {
1039 if (flag)
1040 *out |= tab[j].in;
1041 break;
1042 }
1043 }
1044 if (j == n) {
1045 LOG_ERROR("Unknown key: %s", key);
1046 return TSS2_FAPI_RC_BAD_VALUE;
1047 }
1048 }
1049 } else {
1050 const char *token;
1051 token = json_object_get_string(jso);
1052 int64_t i64;
1053 if (!get_number(token, &i64)) {
1054 LOG_ERROR("Bad value");
1055 return TSS2_FAPI_RC_BAD_VALUE;
1056 }
1057 *out = (TPMA_OBJECT) i64;
1058 if ((int64_t)*out != i64) {
1059 LOG_ERROR("Bad value");
1060 return TSS2_FAPI_RC_BAD_VALUE;
1061 }
1062 return TSS2_RC_SUCCESS;
1063 }
1064 LOG_TRACE("true");
1065 return TSS2_RC_SUCCESS;
1066 }
1067
1068 /** Deserialize a TPMA_LOCALITY json object.
1069 *
1070 * @param[in] jso the json object to be deserialized.
1071 * @param[out] out the deserialzed binary object.
1072 * @retval TSS2_RC_SUCCESS if the function call was a success.
1073 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1074 */
1075 TSS2_RC
1076 ifapi_json_TPMA_LOCALITY_deserialize(json_object *jso, TPMA_LOCALITY *out)
1077 {
1078 struct { TPMA_LOCALITY in; char *name; } tab[] = {
1079 { TPMA_LOCALITY_TPM2_LOC_ZERO, "ZERO" },
1080 { TPMA_LOCALITY_TPM2_LOC_ONE, "ONE" },
1081 { TPMA_LOCALITY_TPM2_LOC_TWO, "TWO" },
1082 { TPMA_LOCALITY_TPM2_LOC_THREE, "THREE" },
1083 { TPMA_LOCALITY_TPM2_LOC_FOUR, "FOUR" },
1084 };
1085 size_t n = sizeof(tab) / sizeof(tab[0]);
1086 size_t i, j;
1087
1088 TPMI_YES_NO flag;
1089 TSS2_RC r;
1090
1091 LOG_TRACE("call");
1092 memset(out, 0, sizeof(TPMA_LOCALITY));
1093 json_type jso_type = json_object_get_type(jso);
1094 if (jso_type == json_type_array) {
1095 /* Cast (size_t) is necessary to support older version of libjson-c */
1096 for (i = 0; i < (size_t)json_object_array_length(jso); i++) {
1097 json_object *jso2 = json_object_array_get_idx(jso, i);
1098 const char *token = strip_prefix(json_object_get_string(jso2),
1099 "TPM_", "TPM2_", "TPMA_", "LOCALITY_",
1100 "TPM2_", "LOC_", NULL);
1101 if (!token) {
1102 LOG_ERROR("Bad object; expected array of strings.");
1103 return TSS2_FAPI_RC_BAD_VALUE;
1104 }
1105 for (j = 0; j < n; j++) {
1106 if (strcasecmp(tab[j].name, token) == 0) {
1107 *out |= tab[j].in;
1108 break;
1109 }
1110 }
1111 if (j == n) {
1112 LOG_ERROR("Unknown value: %s", json_object_get_string(jso2));
1113 return TSS2_FAPI_RC_BAD_VALUE;
1114 }
1115 }
1116 } else if (jso_type == json_type_object) {
1117 json_object_object_foreach(jso, key, val) {
1118 const char *token = strip_prefix(key,
1119 "TPM_", "TPM2_", "TPMA_", "LOCALITY_",
1120 "TPM2_", "LOC_", NULL);
1121 if (strcasecmp(token, "extended") == 0) {
1122 int64_t i64;
1123 if (!get_number(json_object_get_string(val), &i64)) {
1124 LOG_ERROR("Bad value");
1125 return TSS2_FAPI_RC_BAD_VALUE;
1126 }
1127 if (((i64<<5) & ~TPMA_LOCALITY_EXTENDED_MASK) != 0) {
1128 LOG_ERROR("Bad value for extended");
1129 return TSS2_FAPI_RC_BAD_VALUE;
1130 }
1131 *out |= (TPMA_LOCALITY)(i64<<5);
1132 continue;
1133 }
1134 r = get_boolean_from_json(val, &flag);
1135 return_if_error2(r, "Boolean value expected at key: %s", key);
1136 for (j = 0; j < n; j++) {
1137 if (strcasecmp(tab[j].name, token) == 0) {
1138 if (flag)
1139 *out |= tab[j].in;
1140 break;
1141 }
1142 }
1143 if (j == n) {
1144 LOG_ERROR("Unknown key: %s", key);
1145 return TSS2_FAPI_RC_BAD_VALUE;
1146 }
1147 }
1148 } else {
1149 const char *token;
1150 token = json_object_get_string(jso);
1151 int64_t i64;
1152 if (!get_number(token, &i64)) {
1153 LOG_ERROR("Bad value");
1154 return TSS2_FAPI_RC_BAD_VALUE;
1155 }
1156 *out = (TPMA_LOCALITY) i64;
1157 if ((int64_t)*out != i64) {
1158 LOG_ERROR("Bad value");
1159 return TSS2_FAPI_RC_BAD_VALUE;
1160 }
1161 return TSS2_RC_SUCCESS;
1162 }
1163 LOG_TRACE("true");
1164 return TSS2_RC_SUCCESS;
1165 }
1166
1167 /** Deserialize a TPMI_YES_NO json object.
1168 *
1169 * @param[in] jso the json object to be deserialized.
1170 * @param[out] out the deserialzed binary object.
1171 * @retval TSS2_RC_SUCCESS if the function call was a success.
1172 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1173 */
1174 TSS2_RC
1175 ifapi_json_TPMI_YES_NO_deserialize(json_object *jso, TPMI_YES_NO *out)
1176 {
1177 static const struct { TPMI_YES_NO in; const char *name; } tab[] = {
1178 { NO, "NO" },
1179 { YES, "YES" },
1180 };
1181
1182 const char *s = json_object_get_string(jso);
1183 const char *str = strip_prefix(s, "TPM_", "TPM2_", "TPMI_", NULL);
1184 LOG_TRACE("called for %s parsing %s", s, str);
1185
1186 if (str) {
1187 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
1188 if (strcasecmp(str, &tab[i].name[0]) == 0) {
1189 *out = tab[i].in;
1190 return TSS2_RC_SUCCESS;
1191 }
1192 }
1193 }
1194
1195 return ifapi_json_BYTE_deserialize(jso, out);
1196 }
1197
1198 /** Deserialize a TPMI_RH_HIERARCHY json object.
1199 *
1200 * @param[in] jso the json object to be deserialized.
1201 * @param[out] out the deserialzed binary object.
1202 * @retval TSS2_RC_SUCCESS if the function call was a success.
1203 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1204 */
1205 TSS2_RC
1206 ifapi_json_TPMI_RH_HIERARCHY_deserialize(json_object *jso,
1207 TPMI_RH_HIERARCHY *out)
1208 {
1209 static const struct { TPMI_RH_HIERARCHY in; const char *name; } tab[] = {
1210 { TPM2_RH_OWNER, "OWNER" },
1211 { TPM2_RH_PLATFORM, "PLATFORM" },
1212 { TPM2_RH_ENDORSEMENT, "ENDORSEMENT" },
1213 { TPM2_RH_NULL, "NULL" },
1214 };
1215
1216 const char *s = json_object_get_string(jso);
1217 const char *str = strip_prefix(s, "TPM_", "TPM2_", "TPMI_", "RH_", "HIERARCHY_", NULL);
1218 LOG_TRACE("called for %s parsing %s", s, str);
1219
1220 if (str) {
1221 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
1222 if (strcasecmp(str, &tab[i].name[0]) == 0) {
1223 *out = tab[i].in;
1224 return TSS2_RC_SUCCESS;
1225 }
1226 }
1227 }
1228
1229 return ifapi_json_UINT32_deserialize(jso, out);
1230 }
1231
1232 /** Deserialize a TPMI_RH_NV_INDEX json object.
1233 *
1234 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1235 * the function.
1236 */
1237 TSS2_RC
1238 ifapi_json_TPMI_RH_NV_INDEX_deserialize(json_object *jso, TPMI_RH_NV_INDEX *out)
1239 {
1240 return ifapi_json_TPM2_HANDLE_deserialize(jso, out);
1241 }
1242
1243 /** Deserialize a TPMI_ALG_HASH json object.
1244 *
1245 * @param[in] jso the json object to be deserialized.
1246 * @param[out] out the deserialzed binary object.
1247 * @retval TSS2_RC_SUCCESS if the function call was a success.
1248 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1249 */
1250 TSS2_RC
1251 ifapi_json_TPMI_ALG_HASH_deserialize(json_object *jso, TPMI_ALG_HASH *out)
1252 {
1253 SUBTYPE_FILTER(TPMI_ALG_HASH, TPM2_ALG_ID,
1254 TPM2_ALG_SHA1, TPM2_ALG_SHA256, TPM2_ALG_SHA384, TPM2_ALG_SHA512, TPM2_ALG_NULL);
1255 }
1256
1257 /** Deserialize a TPMI_ALG_SYM json object.
1258 *
1259 * @param[in] jso the json object to be deserialized.
1260 * @param[out] out the deserialzed binary object.
1261 * @retval TSS2_RC_SUCCESS if the function call was a success.
1262 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1263 */
1264 TSS2_RC
1265 ifapi_json_TPMI_ALG_SYM_deserialize(json_object *jso, TPMI_ALG_SYM *out)
1266 {
1267 SUBTYPE_FILTER(TPMI_ALG_SYM, TPM2_ALG_ID,
1268 TPM2_ALG_AES, TPM2_ALG_XOR, TPM2_ALG_NULL);
1269 }
1270
1271 /** Deserialize a TPMI_ALG_SYM_OBJECT json object.
1272 *
1273 * @param[in] jso the json object to be deserialized.
1274 * @param[out] out the deserialzed binary object.
1275 * @retval TSS2_RC_SUCCESS if the function call was a success.
1276 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1277 */
1278 TSS2_RC
1279 ifapi_json_TPMI_ALG_SYM_OBJECT_deserialize(json_object *jso,
1280 TPMI_ALG_SYM_OBJECT *out)
1281 {
1282 SUBTYPE_FILTER(TPMI_ALG_SYM_OBJECT, TPM2_ALG_ID,
1283 TPM2_ALG_AES, TPM2_ALG_NULL);
1284 }
1285
1286 /** Deserialize a TPMI_ALG_SYM_MODE json object.
1287 *
1288 * @param[in] jso the json object to be deserialized.
1289 * @param[out] out the deserialzed binary object.
1290 * @retval TSS2_RC_SUCCESS if the function call was a success.
1291 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1292 */
1293 TSS2_RC
1294 ifapi_json_TPMI_ALG_SYM_MODE_deserialize(json_object *jso,
1295 TPMI_ALG_SYM_MODE *out)
1296 {
1297 SUBTYPE_FILTER(TPMI_ALG_SYM_MODE, TPM2_ALG_ID,
1298 TPM2_ALG_CTR, TPM2_ALG_OFB, TPM2_ALG_CBC, TPM2_ALG_CFB, TPM2_ALG_ECB, TPM2_ALG_NULL);
1299 }
1300
1301 /** Deserialize a TPMI_ALG_KDF json object.
1302 *
1303 * @param[in] jso the json object to be deserialized.
1304 * @param[out] out the deserialzed binary object.
1305 * @retval TSS2_RC_SUCCESS if the function call was a success.
1306 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1307 */
1308 TSS2_RC
1309 ifapi_json_TPMI_ALG_KDF_deserialize(json_object *jso, TPMI_ALG_KDF *out)
1310 {
1311 SUBTYPE_FILTER(TPMI_ALG_KDF, TPM2_ALG_ID,
1312 TPM2_ALG_MGF1, TPM2_ALG_KDF1_SP800_56A, TPM2_ALG_KDF1_SP800_108, TPM2_ALG_NULL);
1313 }
1314
1315 /** Deserialize a TPMI_ALG_SIG_SCHEME json object.
1316 *
1317 * @param[in] jso the json object to be deserialized.
1318 * @param[out] out the deserialzed binary object.
1319 * @retval TSS2_RC_SUCCESS if the function call was a success.
1320 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1321 */
1322 TSS2_RC
1323 ifapi_json_TPMI_ALG_SIG_SCHEME_deserialize(json_object *jso,
1324 TPMI_ALG_SIG_SCHEME *out)
1325 {
1326 SUBTYPE_FILTER(TPMI_ALG_SIG_SCHEME, TPM2_ALG_ID,
1327 TPM2_ALG_RSASSA, TPM2_ALG_RSAPSS, TPM2_ALG_ECDSA, TPM2_ALG_ECDAA, TPM2_ALG_SM2,
1328 TPM2_ALG_ECSCHNORR, TPM2_ALG_HMAC, TPM2_ALG_NULL);
1329 }
1330
1331 /** Deserialize a TPMU_HA json object.
1332 *
1333 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
1334 * @param[in] selector The type of the HA object.
1335 * @param[in] jso the json object to be deserialized.
1336 * @param[out] out the deserialzed binary object.
1337 * @retval TSS2_RC_SUCCESS if the function call was a success.
1338 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1339 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1340 */
1341 TSS2_RC
1342 ifapi_json_TPMU_HA_deserialize(
1343 UINT32 selector,
1344 json_object *jso,
1345 TPMU_HA *out)
1346 {
1347 const char *hex_string = json_object_get_string(jso);
1348 size_t size = strlen(hex_string) / 2;
1349 size_t hash_size;
1350 uint8_t *buffer;
1351 TSS2_RC r;
1352
1353 LOG_TRACE("call");
1354 switch (selector) {
1355 case TPM2_ALG_SHA1:
1356 hash_size = TPM2_SHA1_DIGEST_SIZE;
1357 buffer = &out->sha1[0];
1358 break;
1359 case TPM2_ALG_SHA256:
1360 hash_size = TPM2_SHA256_DIGEST_SIZE;
1361 buffer = &out->sha256[0];
1362 break;
1363 case TPM2_ALG_SHA384:
1364 hash_size = TPM2_SHA384_DIGEST_SIZE;
1365 buffer = &out->sha384[0];
1366 break;
1367 case TPM2_ALG_SHA512:
1368 hash_size = TPM2_SHA512_DIGEST_SIZE;
1369 buffer = &out->sha512[0];
1370 break;
1371 case TPM2_ALG_NULL: {
1372 return TSS2_RC_SUCCESS;
1373 }
1374 default:
1375 LOG_TRACE("false");
1376 return TSS2_FAPI_RC_BAD_VALUE;
1377 };
1378 if (hash_size != size) {
1379 return_error(TSS2_FAPI_RC_BAD_VALUE, "Wrong size of digest.");
1380 }
1381 r = ifapi_hex_to_byte_ary(hex_string, size, buffer);
1382 return_if_error(r, "Can't convert hex values.");
1383
1384 return TSS2_RC_SUCCESS;
1385 }
1386
1387 /** Deserialize a TPMT_HA json object.
1388 *
1389 * @param[in] jso the json object to be deserialized.
1390 * @param[out] out the deserialzed binary object.
1391 * @retval TSS2_RC_SUCCESS if the function call was a success.
1392 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1393 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1394 */
1395 TSS2_RC
1396 ifapi_json_TPMT_HA_deserialize(json_object *jso, TPMT_HA *out)
1397 {
1398 json_object *jso2;
1399 TSS2_RC r;
1400 LOG_TRACE("call");
1401 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1402
1403 if (!ifapi_get_sub_object(jso, "hashAlg", &jso2)) {
1404 LOG_ERROR("Bad value");
1405 return TSS2_FAPI_RC_BAD_VALUE;
1406 }
1407 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->hashAlg);
1408 return_if_error(r, "BAD VALUE");
1409 if (out->hashAlg != TPM2_ALG_NULL) {
1410 if (!ifapi_get_sub_object(jso, "digest", &jso2)) {
1411 LOG_ERROR("BAD VALUE");
1412 return TSS2_FAPI_RC_BAD_VALUE;
1413 }
1414 r = ifapi_json_TPMU_HA_deserialize(out->hashAlg, jso2, &out->digest);
1415 return_if_error(r, "BAD VALUE");
1416 }
1417
1418 LOG_TRACE("true");
1419 return TSS2_RC_SUCCESS;
1420 }
1421
1422 /** Deserialize a TPM2B_DIGEST json object.
1423 *
1424 * @param[in] jso the json object to be deserialized.
1425 * @param[out] out the deserialzed binary object.
1426 * @retval TSS2_RC_SUCCESS if the function call was a success.
1427 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1428 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1429 */
1430 TSS2_RC
1431 ifapi_json_TPM2B_DIGEST_deserialize(json_object *jso, TPM2B_DIGEST *out)
1432 {
1433 TSS2_RC r;
1434 LOG_TRACE("call");
1435 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1436
1437 UINT16 size = 0;
1438 r = ifapi_json_byte_deserialize(jso, sizeof(TPMU_HA), (BYTE *)&out->buffer,
1439 &size);
1440 return_if_error(r, "byte serialize");
1441
1442 out->size = size;
1443 return r;
1444 LOG_TRACE("true");
1445 return TSS2_RC_SUCCESS;
1446 }
1447
1448 /** Deserialize a TPM2B_DATA json object.
1449 *
1450 * @param[in] jso the json object to be deserialized.
1451 * @param[out] out the deserialzed binary object.
1452 * @retval TSS2_RC_SUCCESS if the function call was a success.
1453 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1454 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1455 */
1456 TSS2_RC
1457 ifapi_json_TPM2B_DATA_deserialize(json_object *jso, TPM2B_DATA *out)
1458 {
1459 TSS2_RC r;
1460 LOG_TRACE("call");
1461 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1462
1463 UINT16 size = 0;
1464 r = ifapi_json_byte_deserialize(jso, sizeof(TPMT_HA), (BYTE *)&out->buffer,
1465 &size);
1466 return_if_error(r, "byte serialize");
1467
1468 out->size = size;
1469 return r;
1470 LOG_TRACE("true");
1471 return TSS2_RC_SUCCESS;
1472 }
1473
1474 /*** Table 75 - Definition of Types for TPM2B_NONCE ***/
1475
1476 /** Deserialize a TPM2B_NONCE json object.
1477 *
1478 * @param[in] jso the json object to be deserialized.
1479 * @param[out] out the deserialzed binary object.
1480 * @retval TSS2_RC_SUCCESS if the function call was a success.
1481 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1482 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1483 */
1484 TSS2_RC
1485 ifapi_json_TPM2B_NONCE_deserialize(json_object *jso, TPM2B_NONCE *out)
1486 {
1487 LOG_TRACE("call");
1488 return ifapi_json_TPM2B_DIGEST_deserialize(jso, out);
1489 }
1490
1491 /*** Table 77 - Definition of Types for TPM2B_OPERAND ***/
1492
1493 /** Deserialize a TPM2B_OPERAND json object.
1494 *
1495 * @param[in] jso the json object to be deserialized.
1496 * @param[out] out the deserialzed binary object.
1497 * @retval TSS2_RC_SUCCESS if the function call was a success.
1498 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1499 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1500 */
1501 TSS2_RC
1502 ifapi_json_TPM2B_OPERAND_deserialize(json_object *jso, TPM2B_OPERAND *out)
1503 {
1504 LOG_TRACE("call");
1505 return ifapi_json_TPM2B_DIGEST_deserialize(jso, out);
1506 }
1507
1508 /** Deserialize a TPM2B_EVENT json object.
1509 *
1510 * @param[in] jso the json object to be deserialized.
1511 * @param[out] out the deserialzed binary object.
1512 * @retval TSS2_RC_SUCCESS if the function call was a success.
1513 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1514 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1515 */
1516 TSS2_RC
1517 ifapi_json_TPM2B_EVENT_deserialize(json_object *jso, TPM2B_EVENT *out)
1518 {
1519 TSS2_RC r;
1520 LOG_TRACE("call");
1521 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1522
1523 UINT16 size = 0;
1524 r = ifapi_json_byte_deserialize(jso, 1024, (BYTE *)&out->buffer, &size);
1525 return_if_error(r, "byte serialize");
1526
1527 out->size = size;
1528 return r;
1529 LOG_TRACE("true");
1530 return TSS2_RC_SUCCESS;
1531 }
1532
1533 /** Deserialize a TPM2B_MAX_NV_BUFFER json object.
1534 *
1535 * @param[in] jso the json object to be deserialized.
1536 * @param[out] out the deserialzed binary object.
1537 * @retval TSS2_RC_SUCCESS if the function call was a success.
1538 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1539 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1540 */
1541 TSS2_RC
1542 ifapi_json_TPM2B_MAX_NV_BUFFER_deserialize(json_object *jso,
1543 TPM2B_MAX_NV_BUFFER *out)
1544 {
1545 TSS2_RC r;
1546 LOG_TRACE("call");
1547 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1548
1549 UINT16 size = 0;
1550 r = ifapi_json_byte_deserialize(jso, TPM2_MAX_NV_BUFFER_SIZE,
1551 (BYTE *)&out->buffer, &size);
1552 return_if_error(r, "byte serialize");
1553
1554 out->size = size;
1555 return r;
1556 LOG_TRACE("true");
1557 return TSS2_RC_SUCCESS;
1558 }
1559
1560 /** Deserialize a TPM2B_NAME json object.
1561 *
1562 * @param[in] jso the json object to be deserialized.
1563 * @param[out] out the deserialzed binary object.
1564 * @retval TSS2_RC_SUCCESS if the function call was a success.
1565 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1566 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1567 */
1568 TSS2_RC
1569 ifapi_json_TPM2B_NAME_deserialize(json_object *jso, TPM2B_NAME *out)
1570 {
1571 TSS2_RC r;
1572 LOG_TRACE("call");
1573 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1574
1575 UINT16 size = 0;
1576 r = ifapi_json_byte_deserialize(jso, sizeof(TPMU_NAME), (BYTE *)&out->name,
1577 &size);
1578 return_if_error(r, "byte serialize");
1579
1580 out->size = size;
1581 return r;
1582 LOG_TRACE("true");
1583 return TSS2_RC_SUCCESS;
1584 }
1585
1586 /** Deserialize a TPMT_TK_CREATION json object.
1587 *
1588 * @param[in] jso the json object to be deserialized.
1589 * @param[out] out the deserialzed binary object.
1590 * @retval TSS2_RC_SUCCESS if the function call was a success.
1591 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1592 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1593 */
1594 TSS2_RC
1595 ifapi_json_TPMT_TK_CREATION_deserialize(json_object *jso,
1596 TPMT_TK_CREATION *out)
1597 {
1598 json_object *jso2;
1599 TSS2_RC r;
1600 LOG_TRACE("call");
1601 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1602
1603 if (!ifapi_get_sub_object(jso, "tag", &jso2)) {
1604 LOG_ERROR("Bad value");
1605 return TSS2_FAPI_RC_BAD_VALUE;
1606 }
1607 r = ifapi_json_TPM2_ST_deserialize(jso2, &out->tag);
1608 return_if_error(r, "BAD VALUE");
1609 if (out != NULL && out->tag != TPM2_ST_CREATION) {
1610 LOG_ERROR("BAD VALUE %zu != %zu", (size_t)out->tag, (size_t)TPM2_ST_CREATION);
1611 }
1612
1613 if (!ifapi_get_sub_object(jso, "hierarchy", &jso2)) {
1614 LOG_ERROR("Bad value");
1615 return TSS2_FAPI_RC_BAD_VALUE;
1616 }
1617 r = ifapi_json_TPMI_RH_HIERARCHY_deserialize(jso2, &out->hierarchy);
1618 return_if_error(r, "BAD VALUE");
1619
1620 if (!ifapi_get_sub_object(jso, "digest", &jso2)) {
1621 LOG_ERROR("Bad value");
1622 return TSS2_FAPI_RC_BAD_VALUE;
1623 }
1624 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->digest);
1625 return_if_error(r, "BAD VALUE");
1626 LOG_TRACE("true");
1627 return TSS2_RC_SUCCESS;
1628 }
1629
1630 /** Deserialize a TPMT_TK_VERIFIED json object.
1631 *
1632 * @param[in] jso the json object to be deserialized.
1633 * @param[out] out the deserialzed binary object.
1634 * @retval TSS2_RC_SUCCESS if the function call was a success.
1635 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1636 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1637 */
1638 TSS2_RC
1639 ifapi_json_TPMT_TK_VERIFIED_deserialize(json_object *jso,
1640 TPMT_TK_VERIFIED *out)
1641 {
1642 json_object *jso2;
1643 TSS2_RC r;
1644 LOG_TRACE("call");
1645 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1646
1647 if (!ifapi_get_sub_object(jso, "tag", &jso2)) {
1648 LOG_ERROR("Bad value");
1649 return TSS2_FAPI_RC_BAD_VALUE;
1650 }
1651 r = ifapi_json_TPM2_ST_deserialize(jso2, &out->tag);
1652 return_if_error(r, "BAD VALUE");
1653 if (out != NULL && out->tag != TPM2_ST_VERIFIED) {
1654 LOG_ERROR("BAD VALUE %zu != %zu", (size_t)out->tag, (size_t)TPM2_ST_VERIFIED);
1655 }
1656
1657 if (!ifapi_get_sub_object(jso, "hierarchy", &jso2)) {
1658 LOG_ERROR("Bad value");
1659 return TSS2_FAPI_RC_BAD_VALUE;
1660 }
1661 r = ifapi_json_TPMI_RH_HIERARCHY_deserialize(jso2, &out->hierarchy);
1662 return_if_error(r, "BAD VALUE");
1663
1664 if (!ifapi_get_sub_object(jso, "digest", &jso2)) {
1665 LOG_ERROR("Bad value");
1666 return TSS2_FAPI_RC_BAD_VALUE;
1667 }
1668 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->digest);
1669 return_if_error(r, "BAD VALUE");
1670 LOG_TRACE("true");
1671 return TSS2_RC_SUCCESS;
1672 }
1673
1674 /** Deserialize a TPML_DIGEST_VALUES json object.
1675 *
1676 * @param[in] jso the json object to be deserialized.
1677 * @param[out] out the deserialzed binary object.
1678 * @retval TSS2_RC_SUCCESS if the function call was a success.
1679 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1680 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1681 */
1682 TSS2_RC
1683 ifapi_json_TPML_DIGEST_VALUES_deserialize(json_object *jso,
1684 TPML_DIGEST_VALUES *out)
1685 {
1686 TSS2_RC r;
1687 LOG_TRACE("call");
1688 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1689
1690 json_type jso_type = json_object_get_type(jso);
1691 if (jso_type == json_type_array) {
1692 if (json_object_array_length(jso) > (int)TPM2_NUM_PCR_BANKS) {
1693 /* Cast (size_t) is necessary to support older version of libjson-c */
1694 LOG_ERROR("Too many bytes for array (%zu > %zu)",
1695 (size_t)json_object_array_length(jso), (size_t)TPM2_NUM_PCR_BANKS);
1696 return TSS2_FAPI_RC_BAD_VALUE;
1697 }
1698 out->count = json_object_array_length(jso);
1699 size_t i;
1700 /* Cast (size_t) is necessary to support older version of libjson-c */
1701 for (i = 0; i < (size_t)json_object_array_length(jso); i++) {
1702 json_object *jso3 = json_object_array_get_idx(jso, i);
1703 r = ifapi_json_TPMT_HA_deserialize(jso3, &out->digests[i]);
1704 return_if_error(r, "BAD VALUE");
1705 }
1706 return TSS2_RC_SUCCESS;
1707 } else {
1708 LOG_ERROR("BAD VALUE");
1709 return TSS2_FAPI_RC_BAD_VALUE;
1710 }
1711 LOG_TRACE("true");
1712 return TSS2_RC_SUCCESS;
1713 }
1714
1715 /** Deserialize a TPML_PCR_SELECTION json object.
1716 *
1717 * @param[in] jso the json object to be deserialized.
1718 * @param[out] out the deserialzed binary object.
1719 * @retval TSS2_RC_SUCCESS if the function call was a success.
1720 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1721 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1722 */
1723 TSS2_RC
1724 ifapi_json_TPML_PCR_SELECTION_deserialize(json_object *jso,
1725 TPML_PCR_SELECTION *out)
1726 {
1727 TSS2_RC r;
1728 LOG_TRACE("call");
1729 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1730
1731 json_type jso_type = json_object_get_type(jso);
1732 if (jso_type == json_type_array) {
1733 if (json_object_array_length(jso) > (int)TPM2_NUM_PCR_BANKS) {
1734 /* Cast (size_t) is necessary to support older version of libjson-c */
1735 LOG_ERROR("Too many bytes for array (%zu > %zu)",
1736 (size_t)json_object_array_length(jso), (size_t)TPM2_NUM_PCR_BANKS);
1737 return TSS2_FAPI_RC_BAD_VALUE;
1738 }
1739 out->count = json_object_array_length(jso);
1740 size_t i;
1741 /* Cast (size_t) is necessary to support older version of libjson-c */
1742 for (i = 0; i < (size_t)json_object_array_length(jso); i++) {
1743 json_object *jso3 = json_object_array_get_idx(jso, i);
1744 r = ifapi_json_TPMS_PCR_SELECTION_deserialize(jso3, &out->pcrSelections[i]);
1745 return_if_error(r, "BAD VALUE");
1746 }
1747 return TSS2_RC_SUCCESS;
1748 } else {
1749 LOG_ERROR("BAD VALUE");
1750 return TSS2_FAPI_RC_BAD_VALUE;
1751 }
1752 LOG_TRACE("true");
1753 return TSS2_RC_SUCCESS;
1754 }
1755
1756 /** Deserialize a TPMS_CLOCK_INFO json object.
1757 *
1758 * @param[in] jso the json object to be deserialized.
1759 * @param[out] out the deserialzed binary object.
1760 * @retval TSS2_RC_SUCCESS if the function call was a success.
1761 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1762 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1763 */
1764 TSS2_RC
1765 ifapi_json_TPMS_CLOCK_INFO_deserialize(json_object *jso, TPMS_CLOCK_INFO *out)
1766 {
1767 json_object *jso2;
1768 TSS2_RC r;
1769 LOG_TRACE("call");
1770 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1771
1772 if (!ifapi_get_sub_object(jso, "clock", &jso2)) {
1773 LOG_ERROR("Bad value");
1774 return TSS2_FAPI_RC_BAD_VALUE;
1775 }
1776 r = ifapi_json_UINT64_deserialize(jso2, &out->clock);
1777 return_if_error(r, "BAD VALUE");
1778
1779 if (!ifapi_get_sub_object(jso, "resetCount", &jso2)) {
1780 LOG_ERROR("Bad value");
1781 return TSS2_FAPI_RC_BAD_VALUE;
1782 }
1783 r = ifapi_json_UINT32_deserialize(jso2, &out->resetCount);
1784 return_if_error(r, "BAD VALUE");
1785
1786 if (!ifapi_get_sub_object(jso, "restartCount", &jso2)) {
1787 LOG_ERROR("Bad value");
1788 return TSS2_FAPI_RC_BAD_VALUE;
1789 }
1790 r = ifapi_json_UINT32_deserialize(jso2, &out->restartCount);
1791 return_if_error(r, "BAD VALUE");
1792
1793 if (!ifapi_get_sub_object(jso, "safe", &jso2)) {
1794 LOG_ERROR("Bad value");
1795 return TSS2_FAPI_RC_BAD_VALUE;
1796 }
1797 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->safe);
1798 return_if_error(r, "BAD VALUE");
1799 LOG_TRACE("true");
1800 return TSS2_RC_SUCCESS;
1801 }
1802
1803 /** Deserialize a TPMS_TIME_INFO json object.
1804 *
1805 * @param[in] jso the json object to be deserialized.
1806 * @param[out] out the deserialzed binary object.
1807 * @retval TSS2_RC_SUCCESS if the function call was a success.
1808 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1809 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1810 */
1811 TSS2_RC
1812 ifapi_json_TPMS_TIME_INFO_deserialize(json_object *jso, TPMS_TIME_INFO *out)
1813 {
1814 json_object *jso2;
1815 TSS2_RC r;
1816 LOG_TRACE("call");
1817 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1818
1819 if (!ifapi_get_sub_object(jso, "time", &jso2)) {
1820 LOG_ERROR("Bad value");
1821 return TSS2_FAPI_RC_BAD_VALUE;
1822 }
1823 r = ifapi_json_UINT64_deserialize(jso2, &out->time);
1824 return_if_error(r, "BAD VALUE");
1825
1826 if (!ifapi_get_sub_object(jso, "clockInfo", &jso2)) {
1827 LOG_ERROR("Bad value");
1828 return TSS2_FAPI_RC_BAD_VALUE;
1829 }
1830 r = ifapi_json_TPMS_CLOCK_INFO_deserialize(jso2, &out->clockInfo);
1831 return_if_error(r, "BAD VALUE");
1832 LOG_TRACE("true");
1833 return TSS2_RC_SUCCESS;
1834 }
1835
1836 /** Deserialize a TPMS_TIME_ATTEST_INFO json object.
1837 *
1838 * @param[in] jso the json object to be deserialized.
1839 * @param[out] out the deserialzed binary object.
1840 * @retval TSS2_RC_SUCCESS if the function call was a success.
1841 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1842 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1843 */
1844 TSS2_RC
1845 ifapi_json_TPMS_TIME_ATTEST_INFO_deserialize(json_object *jso,
1846 TPMS_TIME_ATTEST_INFO *out)
1847 {
1848 json_object *jso2;
1849 TSS2_RC r;
1850 LOG_TRACE("call");
1851 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1852
1853 if (!ifapi_get_sub_object(jso, "time", &jso2)) {
1854 LOG_ERROR("Bad value");
1855 return TSS2_FAPI_RC_BAD_VALUE;
1856 }
1857 r = ifapi_json_TPMS_TIME_INFO_deserialize(jso2, &out->time);
1858 return_if_error(r, "BAD VALUE");
1859
1860 if (!ifapi_get_sub_object(jso, "firmwareVersion", &jso2)) {
1861 LOG_ERROR("Bad value");
1862 return TSS2_FAPI_RC_BAD_VALUE;
1863 }
1864 r = ifapi_json_UINT64_deserialize(jso2, &out->firmwareVersion);
1865 return_if_error(r, "BAD VALUE");
1866 LOG_TRACE("true");
1867 return TSS2_RC_SUCCESS;
1868 }
1869
1870 /** Deserialize a TPMS_CERTIFY_INFO json object.
1871 *
1872 * @param[in] jso the json object to be deserialized.
1873 * @param[out] out the deserialzed binary object.
1874 * @retval TSS2_RC_SUCCESS if the function call was a success.
1875 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1876 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1877 */
1878 TSS2_RC
1879 ifapi_json_TPMS_CERTIFY_INFO_deserialize(json_object *jso,
1880 TPMS_CERTIFY_INFO *out)
1881 {
1882 json_object *jso2;
1883 TSS2_RC r;
1884 LOG_TRACE("call");
1885 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1886
1887 if (!ifapi_get_sub_object(jso, "name", &jso2)) {
1888 LOG_ERROR("Bad value");
1889 return TSS2_FAPI_RC_BAD_VALUE;
1890 }
1891 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->name);
1892 return_if_error(r, "BAD VALUE");
1893
1894 if (!ifapi_get_sub_object(jso, "qualifiedName", &jso2)) {
1895 LOG_ERROR("Bad value");
1896 return TSS2_FAPI_RC_BAD_VALUE;
1897 }
1898 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->qualifiedName);
1899 return_if_error(r, "BAD VALUE");
1900 LOG_TRACE("true");
1901 return TSS2_RC_SUCCESS;
1902 }
1903
1904 /** Deserialize a TPMS_QUOTE_INFO json object.
1905 *
1906 * @param[in] jso the json object to be deserialized.
1907 * @param[out] out the deserialzed binary object.
1908 * @retval TSS2_RC_SUCCESS if the function call was a success.
1909 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1910 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1911 */
1912 TSS2_RC
1913 ifapi_json_TPMS_QUOTE_INFO_deserialize(json_object *jso, TPMS_QUOTE_INFO *out)
1914 {
1915 json_object *jso2;
1916 TSS2_RC r;
1917 LOG_TRACE("call");
1918 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1919
1920 if (!ifapi_get_sub_object(jso, "pcrSelect", &jso2)) {
1921 LOG_ERROR("Bad value");
1922 return TSS2_FAPI_RC_BAD_VALUE;
1923 }
1924 r = ifapi_json_TPML_PCR_SELECTION_deserialize(jso2, &out->pcrSelect);
1925 return_if_error(r, "BAD VALUE");
1926
1927 if (!ifapi_get_sub_object(jso, "pcrDigest", &jso2)) {
1928 LOG_ERROR("Bad value");
1929 return TSS2_FAPI_RC_BAD_VALUE;
1930 }
1931 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->pcrDigest);
1932 return_if_error(r, "BAD VALUE");
1933 LOG_TRACE("true");
1934 return TSS2_RC_SUCCESS;
1935 }
1936
1937 /** Deserialize a TPMS_COMMAND_AUDIT_INFO json object.
1938 *
1939 * @param[in] jso the json object to be deserialized.
1940 * @param[out] out the deserialzed binary object.
1941 * @retval TSS2_RC_SUCCESS if the function call was a success.
1942 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1943 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1944 */
1945 TSS2_RC
1946 ifapi_json_TPMS_COMMAND_AUDIT_INFO_deserialize(json_object *jso,
1947 TPMS_COMMAND_AUDIT_INFO *out)
1948 {
1949 json_object *jso2;
1950 TSS2_RC r;
1951 LOG_TRACE("call");
1952 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1953
1954 if (!ifapi_get_sub_object(jso, "auditCounter", &jso2)) {
1955 LOG_ERROR("Bad value");
1956 return TSS2_FAPI_RC_BAD_VALUE;
1957 }
1958 r = ifapi_json_UINT64_deserialize(jso2, &out->auditCounter);
1959 return_if_error(r, "BAD VALUE");
1960
1961 if (!ifapi_get_sub_object(jso, "digestAlg", &jso2)) {
1962 LOG_ERROR("Bad value");
1963 return TSS2_FAPI_RC_BAD_VALUE;
1964 }
1965 r = ifapi_json_TPM2_ALG_ID_deserialize(jso2, &out->digestAlg);
1966 return_if_error(r, "BAD VALUE");
1967
1968 if (!ifapi_get_sub_object(jso, "auditDigest", &jso2)) {
1969 LOG_ERROR("Bad value");
1970 return TSS2_FAPI_RC_BAD_VALUE;
1971 }
1972 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->auditDigest);
1973 return_if_error(r, "BAD VALUE");
1974
1975 if (!ifapi_get_sub_object(jso, "commandDigest", &jso2)) {
1976 LOG_ERROR("Bad value");
1977 return TSS2_FAPI_RC_BAD_VALUE;
1978 }
1979 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->commandDigest);
1980 return_if_error(r, "BAD VALUE");
1981 LOG_TRACE("true");
1982 return TSS2_RC_SUCCESS;
1983 }
1984
1985 /** Deserialize a TPMS_SESSION_AUDIT_INFO json object.
1986 *
1987 * @param[in] jso the json object to be deserialized.
1988 * @param[out] out the deserialzed binary object.
1989 * @retval TSS2_RC_SUCCESS if the function call was a success.
1990 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
1991 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1992 */
1993 TSS2_RC
1994 ifapi_json_TPMS_SESSION_AUDIT_INFO_deserialize(json_object *jso,
1995 TPMS_SESSION_AUDIT_INFO *out)
1996 {
1997 json_object *jso2;
1998 TSS2_RC r;
1999 LOG_TRACE("call");
2000 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2001
2002 if (!ifapi_get_sub_object(jso, "exclusiveSession", &jso2)) {
2003 LOG_ERROR("Bad value");
2004 return TSS2_FAPI_RC_BAD_VALUE;
2005 }
2006 r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->exclusiveSession);
2007 return_if_error(r, "BAD VALUE");
2008
2009 if (!ifapi_get_sub_object(jso, "sessionDigest", &jso2)) {
2010 LOG_ERROR("Bad value");
2011 return TSS2_FAPI_RC_BAD_VALUE;
2012 }
2013 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->sessionDigest);
2014 return_if_error(r, "BAD VALUE");
2015 LOG_TRACE("true");
2016 return TSS2_RC_SUCCESS;
2017 }
2018
2019 /** Deserialize a TPMS_CREATION_INFO json object.
2020 *
2021 * @param[in] jso the json object to be deserialized.
2022 * @param[out] out the deserialzed binary object.
2023 * @retval TSS2_RC_SUCCESS if the function call was a success.
2024 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2025 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2026 */
2027 TSS2_RC
2028 ifapi_json_TPMS_CREATION_INFO_deserialize(json_object *jso,
2029 TPMS_CREATION_INFO *out)
2030 {
2031 json_object *jso2;
2032 TSS2_RC r;
2033 LOG_TRACE("call");
2034 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2035
2036 if (!ifapi_get_sub_object(jso, "objectName", &jso2)) {
2037 LOG_ERROR("Bad value");
2038 return TSS2_FAPI_RC_BAD_VALUE;
2039 }
2040 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->objectName);
2041 return_if_error(r, "BAD VALUE");
2042
2043 if (!ifapi_get_sub_object(jso, "creationHash", &jso2)) {
2044 LOG_ERROR("Bad value");
2045 return TSS2_FAPI_RC_BAD_VALUE;
2046 }
2047 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->creationHash);
2048 return_if_error(r, "BAD VALUE");
2049 LOG_TRACE("true");
2050 return TSS2_RC_SUCCESS;
2051 }
2052
2053 /** Deserialize a TPMS_NV_CERTIFY_INFO json object.
2054 *
2055 * @param[in] jso the json object to be deserialized.
2056 * @param[out] out the deserialzed binary object.
2057 * @retval TSS2_RC_SUCCESS if the function call was a success.
2058 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2059 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2060 */
2061 TSS2_RC
2062 ifapi_json_TPMS_NV_CERTIFY_INFO_deserialize(json_object *jso,
2063 TPMS_NV_CERTIFY_INFO *out)
2064 {
2065 json_object *jso2;
2066 TSS2_RC r;
2067 LOG_TRACE("call");
2068 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2069
2070 if (!ifapi_get_sub_object(jso, "indexName", &jso2)) {
2071 LOG_ERROR("Bad value");
2072 return TSS2_FAPI_RC_BAD_VALUE;
2073 }
2074 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->indexName);
2075 return_if_error(r, "BAD VALUE");
2076
2077 if (!ifapi_get_sub_object(jso, "offset", &jso2)) {
2078 LOG_ERROR("Bad value");
2079 return TSS2_FAPI_RC_BAD_VALUE;
2080 }
2081 r = ifapi_json_UINT16_deserialize(jso2, &out->offset);
2082 return_if_error(r, "BAD VALUE");
2083
2084 if (!ifapi_get_sub_object(jso, "nvContents", &jso2)) {
2085 LOG_ERROR("Bad value");
2086 return TSS2_FAPI_RC_BAD_VALUE;
2087 }
2088 r = ifapi_json_TPM2B_MAX_NV_BUFFER_deserialize(jso2, &out->nvContents);
2089 return_if_error(r, "BAD VALUE");
2090 LOG_TRACE("true");
2091 return TSS2_RC_SUCCESS;
2092 }
2093
2094 /** Deserialize a TPMI_ST_ATTEST json object.
2095 *
2096 * @param[in] jso the json object to be deserialized.
2097 * @param[out] out the deserialzed binary object.
2098 * @retval TSS2_RC_SUCCESS if the function call was a success.
2099 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2100 */
2101 TSS2_RC
2102 ifapi_json_TPMI_ST_ATTEST_deserialize(json_object *jso, TPMI_ST_ATTEST *out)
2103 {
2104 SUBTYPE_FILTER(TPMI_ST_ATTEST, TPM2_ST,
2105 TPM2_ST_ATTEST_CERTIFY, TPM2_ST_ATTEST_QUOTE, TPM2_ST_ATTEST_SESSION_AUDIT,
2106 TPM2_ST_ATTEST_COMMAND_AUDIT, TPM2_ST_ATTEST_TIME, TPM2_ST_ATTEST_CREATION,
2107 TPM2_ST_ATTEST_NV);
2108 }
2109
2110 /** Deserialize a TPMU_ATTEST json object.
2111 *
2112 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
2113 * @param[in] selector The type the attest.
2114 * @param[in] jso the json object to be deserialized.
2115 * @param[out] out the deserialzed binary object.
2116 * @retval TSS2_RC_SUCCESS if the function call was a success.
2117 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2118 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2119 */
2120 TSS2_RC
2121 ifapi_json_TPMU_ATTEST_deserialize(
2122 UINT32 selector,
2123 json_object *jso,
2124 TPMU_ATTEST *out)
2125 {
2126 LOG_TRACE("call");
2127 switch (selector) {
2128 case TPM2_ST_ATTEST_CERTIFY:
2129 return ifapi_json_TPMS_CERTIFY_INFO_deserialize(jso, &out->certify);
2130 case TPM2_ST_ATTEST_CREATION:
2131 return ifapi_json_TPMS_CREATION_INFO_deserialize(jso, &out->creation);
2132 case TPM2_ST_ATTEST_QUOTE:
2133 return ifapi_json_TPMS_QUOTE_INFO_deserialize(jso, &out->quote);
2134 case TPM2_ST_ATTEST_COMMAND_AUDIT:
2135 return ifapi_json_TPMS_COMMAND_AUDIT_INFO_deserialize(jso, &out->commandAudit);
2136 case TPM2_ST_ATTEST_SESSION_AUDIT:
2137 return ifapi_json_TPMS_SESSION_AUDIT_INFO_deserialize(jso, &out->sessionAudit);
2138 case TPM2_ST_ATTEST_TIME:
2139 return ifapi_json_TPMS_TIME_ATTEST_INFO_deserialize(jso, &out->time);
2140 case TPM2_ST_ATTEST_NV:
2141 return ifapi_json_TPMS_NV_CERTIFY_INFO_deserialize(jso, &out->nv);
2142 default:
2143 LOG_TRACE("false");
2144 return TSS2_FAPI_RC_BAD_VALUE;
2145 };
2146 }
2147
2148 /** Deserialize a TPMS_ATTEST json object.
2149 *
2150 * @param[in] jso the json object to be deserialized.
2151 * @param[out] out the deserialzed binary object.
2152 * @retval TSS2_RC_SUCCESS if the function call was a success.
2153 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2154 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2155 */
2156 TSS2_RC
2157 ifapi_json_TPMS_ATTEST_deserialize(json_object *jso, TPMS_ATTEST *out)
2158 {
2159 json_object *jso2;
2160 TSS2_RC r;
2161 LOG_TRACE("call");
2162 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2163
2164 if (!ifapi_get_sub_object(jso, "magic", &jso2)) {
2165 LOG_ERROR("Bad value");
2166 return TSS2_FAPI_RC_BAD_VALUE;
2167 }
2168 r = ifapi_json_TPM2_GENERATED_deserialize(jso2, &out->magic);
2169 return_if_error(r, "BAD VALUE");
2170
2171 if (!ifapi_get_sub_object(jso, "type", &jso2)) {
2172 LOG_ERROR("Bad value");
2173 return TSS2_FAPI_RC_BAD_VALUE;
2174 }
2175 r = ifapi_json_TPMI_ST_ATTEST_deserialize(jso2, &out->type);
2176 return_if_error(r, "BAD VALUE");
2177
2178 if (!ifapi_get_sub_object(jso, "qualifiedSigner", &jso2)) {
2179 LOG_ERROR("Bad value");
2180 return TSS2_FAPI_RC_BAD_VALUE;
2181 }
2182 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->qualifiedSigner);
2183 return_if_error(r, "BAD VALUE");
2184
2185 if (!ifapi_get_sub_object(jso, "extraData", &jso2)) {
2186 LOG_ERROR("Bad value");
2187 return TSS2_FAPI_RC_BAD_VALUE;
2188 }
2189 r = ifapi_json_TPM2B_DATA_deserialize(jso2, &out->extraData);
2190 return_if_error(r, "BAD VALUE");
2191
2192 if (!ifapi_get_sub_object(jso, "clockInfo", &jso2)) {
2193 LOG_ERROR("Bad value");
2194 return TSS2_FAPI_RC_BAD_VALUE;
2195 }
2196 r = ifapi_json_TPMS_CLOCK_INFO_deserialize(jso2, &out->clockInfo);
2197 return_if_error(r, "BAD VALUE");
2198
2199 if (!ifapi_get_sub_object(jso, "firmwareVersion", &jso2)) {
2200 LOG_ERROR("Bad value");
2201 return TSS2_FAPI_RC_BAD_VALUE;
2202 }
2203 r = ifapi_json_UINT64_deserialize(jso2, &out->firmwareVersion);
2204 return_if_error(r, "BAD VALUE");
2205 if (!ifapi_get_sub_object(jso, "attested", &jso2)) {
2206 LOG_ERROR("BAD VALUE");
2207 return TSS2_FAPI_RC_BAD_VALUE;
2208 }
2209 r = ifapi_json_TPMU_ATTEST_deserialize(out->type, jso2, &out->attested);
2210 return_if_error(r, "BAD VALUE");
2211
2212 LOG_TRACE("true");
2213 return TSS2_RC_SUCCESS;
2214 }
2215
2216 /** Deserialize a TPMI_AES_KEY_BITS json object.
2217 *
2218 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2219 * the function.
2220 */
2221 TSS2_RC
2222 ifapi_json_TPMI_AES_KEY_BITS_deserialize(json_object *jso, TPMI_AES_KEY_BITS *out)
2223 {
2224 SUBTYPE_FILTER(TPMI_AES_KEY_BITS, UINT16,
2225 128, 192, 256);
2226 }
2227
2228 /** Deserialize a TPMU_SYM_KEY_BITS json object.
2229 *
2230 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
2231 * @param[in] selector The type the symmetric algorithm.
2232 * @param[in] jso the json object to be deserialized.
2233 * @param[out] out the deserialzed binary object.
2234 * @retval TSS2_RC_SUCCESS if the function call was a success.
2235 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2236 */
2237 TSS2_RC
2238 ifapi_json_TPMU_SYM_KEY_BITS_deserialize(
2239 UINT32 selector,
2240 json_object *jso,
2241 TPMU_SYM_KEY_BITS *out)
2242 {
2243 LOG_TRACE("call");
2244 switch (selector) {
2245 case TPM2_ALG_AES:
2246 return ifapi_json_TPMI_AES_KEY_BITS_deserialize(jso, &out->aes);
2247 case TPM2_ALG_XOR:
2248 return ifapi_json_TPMI_ALG_HASH_deserialize(jso, &out->exclusiveOr);
2249
2250 case TPM2_ALG_NULL: {
2251 return TSS2_RC_SUCCESS;
2252 }
2253 default:
2254 LOG_TRACE("false");
2255 return TSS2_FAPI_RC_BAD_VALUE;
2256 };
2257 }
2258
2259 /** Deserialize a TPMU_SYM_MODE json object.
2260 *
2261 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
2262 * @param[in] selector The type the symmetric algorithm.
2263 * @param[in] jso the json object to be deserialized.
2264 * @param[out] out the deserialzed binary object.
2265 * @retval TSS2_RC_SUCCESS if the function call was a success.
2266 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2267 */
2268 TSS2_RC
2269 ifapi_json_TPMU_SYM_MODE_deserialize(
2270 UINT32 selector,
2271 json_object *jso,
2272 TPMU_SYM_MODE *out)
2273 {
2274 LOG_TRACE("call");
2275 switch (selector) {
2276 case TPM2_ALG_AES:
2277 return ifapi_json_TPMI_ALG_SYM_MODE_deserialize(jso, &out->aes);
2278
2279 case TPM2_ALG_NULL: {
2280 return TSS2_RC_SUCCESS;
2281 }
2282 default:
2283 LOG_TRACE("false");
2284 return TSS2_FAPI_RC_BAD_VALUE;
2285 };
2286 }
2287
2288 /** Deserialize a TPMT_SYM_DEF json object.
2289 *
2290 * @param[in] jso the json object to be deserialized.
2291 * @param[out] out the deserialzed binary object.
2292 * @retval TSS2_RC_SUCCESS if the function call was a success.
2293 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2294 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2295 */
2296 TSS2_RC
2297 ifapi_json_TPMT_SYM_DEF_deserialize(json_object *jso, TPMT_SYM_DEF *out)
2298 {
2299 json_object *jso2;
2300 TSS2_RC r;
2301 LOG_TRACE("call");
2302 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2303
2304 if (!ifapi_get_sub_object(jso, "algorithm", &jso2)) {
2305 LOG_ERROR("Bad value");
2306 return TSS2_FAPI_RC_BAD_VALUE;
2307 }
2308 r = ifapi_json_TPMI_ALG_SYM_deserialize(jso2, &out->algorithm);
2309 return_if_error(r, "BAD VALUE");
2310 if (out->algorithm != TPM2_ALG_NULL) {
2311 if (!ifapi_get_sub_object(jso, "keyBits", &jso2)) {
2312 LOG_ERROR("BAD VALUE");
2313 return TSS2_FAPI_RC_BAD_VALUE;
2314 }
2315 r = ifapi_json_TPMU_SYM_KEY_BITS_deserialize(out->algorithm, jso2,
2316 &out->keyBits);
2317 return_if_error(r, "BAD VALUE");
2318 }
2319
2320 if (out->algorithm != TPM2_ALG_NULL) {
2321 if (!ifapi_get_sub_object(jso, "mode", &jso2)) {
2322 LOG_ERROR("BAD VALUE");
2323 return TSS2_FAPI_RC_BAD_VALUE;
2324 }
2325 r = ifapi_json_TPMU_SYM_MODE_deserialize(out->algorithm, jso2, &out->mode);
2326 return_if_error(r, "BAD VALUE");
2327 }
2328
2329 LOG_TRACE("true");
2330 return TSS2_RC_SUCCESS;
2331 }
2332
2333 /** Deserialize a TPMT_SYM_DEF_OBJECT json object.
2334 *
2335 * @param[in] jso the json object to be deserialized.
2336 * @param[out] out the deserialzed binary object.
2337 * @retval TSS2_RC_SUCCESS if the function call was a success.
2338 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2339 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2340 */
2341 TSS2_RC
2342 ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(json_object *jso,
2343 TPMT_SYM_DEF_OBJECT *out)
2344 {
2345 json_object *jso2;
2346 TSS2_RC r;
2347 LOG_TRACE("call");
2348 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2349
2350 if (!ifapi_get_sub_object(jso, "algorithm", &jso2)) {
2351 LOG_ERROR("Bad value");
2352 return TSS2_FAPI_RC_BAD_VALUE;
2353 }
2354 r = ifapi_json_TPMI_ALG_SYM_OBJECT_deserialize(jso2, &out->algorithm);
2355 return_if_error(r, "BAD VALUE");
2356 if (out->algorithm != TPM2_ALG_NULL) {
2357 if (!ifapi_get_sub_object(jso, "keyBits", &jso2)) {
2358 LOG_ERROR("BAD VALUE");
2359 return TSS2_FAPI_RC_BAD_VALUE;
2360 }
2361 r = ifapi_json_TPMU_SYM_KEY_BITS_deserialize(out->algorithm, jso2,
2362 &out->keyBits);
2363 return_if_error(r, "BAD VALUE");
2364 }
2365
2366 if (out->algorithm != TPM2_ALG_NULL) {
2367 if (!ifapi_get_sub_object(jso, "mode", &jso2)) {
2368 LOG_ERROR("BAD VALUE");
2369 return TSS2_FAPI_RC_BAD_VALUE;
2370 }
2371 r = ifapi_json_TPMU_SYM_MODE_deserialize(out->algorithm, jso2, &out->mode);
2372 return_if_error(r, "BAD VALUE");
2373 }
2374
2375 LOG_TRACE("true");
2376 return TSS2_RC_SUCCESS;
2377 }
2378
2379 /** Deserialize a TPMS_SYMCIPHER_PARMS json object.
2380 *
2381 * @param[in] jso the json object to be deserialized.
2382 * @param[out] out the deserialzed binary object.
2383 * @retval TSS2_RC_SUCCESS if the function call was a success.
2384 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2385 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2386 */
2387 TSS2_RC
2388 ifapi_json_TPMS_SYMCIPHER_PARMS_deserialize(json_object *jso,
2389 TPMS_SYMCIPHER_PARMS *out)
2390 {
2391 json_object *jso2;
2392 TSS2_RC r;
2393 LOG_TRACE("call");
2394 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2395
2396 if (!ifapi_get_sub_object(jso, "sym", &jso2)) {
2397 LOG_ERROR("Bad value");
2398 return TSS2_FAPI_RC_BAD_VALUE;
2399 }
2400 r = ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(jso2, &out->sym);
2401 return_if_error(r, "BAD VALUE");
2402 LOG_TRACE("true");
2403 return TSS2_RC_SUCCESS;
2404 }
2405
2406 /** Deserialize a TPMS_SCHEME_HASH json object.
2407 *
2408 * @param[in] jso the json object to be deserialized.
2409 * @param[out] out the deserialzed binary object.
2410 * @retval TSS2_RC_SUCCESS if the function call was a success.
2411 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2412 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2413 */
2414 TSS2_RC
2415 ifapi_json_TPMS_SCHEME_HASH_deserialize(json_object *jso,
2416 TPMS_SCHEME_HASH *out)
2417 {
2418 json_object *jso2;
2419 TSS2_RC r;
2420 LOG_TRACE("call");
2421 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2422
2423 if (!ifapi_get_sub_object(jso, "hashAlg", &jso2)) {
2424 LOG_ERROR("Bad value");
2425 return TSS2_FAPI_RC_BAD_VALUE;
2426 }
2427 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->hashAlg);
2428 return_if_error(r, "BAD VALUE");
2429 LOG_TRACE("true");
2430 return TSS2_RC_SUCCESS;
2431 }
2432
2433 /** Deserialize a TPMS_SCHEME_ECDAA json object.
2434 *
2435 * @param[in] jso the json object to be deserialized.
2436 * @param[out] out the deserialzed binary object.
2437 * @retval TSS2_RC_SUCCESS if the function call was a success.
2438 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2439 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2440 */
2441 TSS2_RC
2442 ifapi_json_TPMS_SCHEME_ECDAA_deserialize(json_object *jso,
2443 TPMS_SCHEME_ECDAA *out)
2444 {
2445 json_object *jso2;
2446 TSS2_RC r;
2447 LOG_TRACE("call");
2448 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2449
2450 if (!ifapi_get_sub_object(jso, "hashAlg", &jso2)) {
2451 LOG_ERROR("Bad value");
2452 return TSS2_FAPI_RC_BAD_VALUE;
2453 }
2454 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->hashAlg);
2455 return_if_error(r, "BAD VALUE");
2456
2457 if (!ifapi_get_sub_object(jso, "count", &jso2)) {
2458 LOG_ERROR("Bad value");
2459 return TSS2_FAPI_RC_BAD_VALUE;
2460 }
2461 r = ifapi_json_UINT16_deserialize(jso2, &out->count);
2462 return_if_error(r, "BAD VALUE");
2463 LOG_TRACE("true");
2464 return TSS2_RC_SUCCESS;
2465 }
2466
2467 /** Deserialize a TPMI_ALG_KEYEDHASH_SCHEME json object.
2468 *
2469 * @param[in] jso the json object to be deserialized.
2470 * @param[out] out the deserialzed binary object.
2471 * @retval TSS2_RC_SUCCESS if the function call was a success.
2472 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2473 */
2474 TSS2_RC
2475 ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_deserialize(json_object *jso,
2476 TPMI_ALG_KEYEDHASH_SCHEME *out)
2477 {
2478 SUBTYPE_FILTER(TPMI_ALG_KEYEDHASH_SCHEME, TPM2_ALG_ID,
2479 TPM2_ALG_HMAC, TPM2_ALG_XOR, TPM2_ALG_NULL);
2480 }
2481
2482 /*** Table 144 - Definition of Types for HMAC_SIG_SCHEME ***/
2483
2484 /** Deserialize a TPMS_SCHEME_HMAC json object.
2485 *
2486 * @param[in] jso the json object to be deserialized.
2487 * @param[out] out the deserialzed binary object.
2488 * @retval TSS2_RC_SUCCESS if the function call was a success.
2489 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2490 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2491 */
2492 TSS2_RC
2493 ifapi_json_TPMS_SCHEME_HMAC_deserialize(json_object *jso, TPMS_SCHEME_HMAC *out)
2494 {
2495 LOG_TRACE("call");
2496 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2497 }
2498
2499 /** Deserialize a TPMS_SCHEME_XOR json object.
2500 *
2501 * @param[in] jso the json object to be deserialized.
2502 * @param[out] out the deserialzed binary object.
2503 * @retval TSS2_RC_SUCCESS if the function call was a success.
2504 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2505 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2506 */
2507 TSS2_RC
2508 ifapi_json_TPMS_SCHEME_XOR_deserialize(json_object *jso, TPMS_SCHEME_XOR *out)
2509 {
2510 json_object *jso2;
2511 TSS2_RC r;
2512 LOG_TRACE("call");
2513 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2514
2515 if (!ifapi_get_sub_object(jso, "hashAlg", &jso2)) {
2516 LOG_ERROR("Bad value");
2517 return TSS2_FAPI_RC_BAD_VALUE;
2518 }
2519 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->hashAlg);
2520 return_if_error(r, "BAD VALUE");
2521
2522 if (!ifapi_get_sub_object(jso, "kdf", &jso2)) {
2523 LOG_ERROR("Bad value");
2524 return TSS2_FAPI_RC_BAD_VALUE;
2525 }
2526 r = ifapi_json_TPMI_ALG_KDF_deserialize(jso2, &out->kdf);
2527 return_if_error(r, "BAD VALUE");
2528 LOG_TRACE("true");
2529 return TSS2_RC_SUCCESS;
2530 }
2531
2532 /** Deserialize a TPMU_SCHEME_KEYEDHASH json object.
2533 *
2534 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
2535 * @param[in] selector The type the keyedhash scheme.
2536 * @param[in] jso the json object to be deserialized.
2537 * @param[out] out the deserialzed binary object.
2538 * @retval TSS2_RC_SUCCESS if the function call was a success.
2539 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2540 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2541 */
2542 TSS2_RC
2543 ifapi_json_TPMU_SCHEME_KEYEDHASH_deserialize(
2544 UINT32 selector,
2545 json_object *jso,
2546 TPMU_SCHEME_KEYEDHASH *out)
2547 {
2548 LOG_TRACE("call");
2549 switch (selector) {
2550 case TPM2_ALG_HMAC:
2551 return ifapi_json_TPMS_SCHEME_HMAC_deserialize(jso, &out->hmac);
2552 case TPM2_ALG_XOR:
2553 return ifapi_json_TPMS_SCHEME_XOR_deserialize(jso, &out->exclusiveOr);
2554
2555 case TPM2_ALG_NULL: {
2556 return TSS2_RC_SUCCESS;
2557 }
2558 default:
2559 LOG_TRACE("false");
2560 return TSS2_FAPI_RC_BAD_VALUE;
2561 };
2562 }
2563
2564 /** Deserialize a TPMT_KEYEDHASH_SCHEME json object.
2565 *
2566 * @param[in] jso the json object to be deserialized.
2567 * @param[out] out the deserialzed binary object.
2568 * @retval TSS2_RC_SUCCESS if the function call was a success.
2569 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2570 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2571 */
2572 TSS2_RC
2573 ifapi_json_TPMT_KEYEDHASH_SCHEME_deserialize(json_object *jso,
2574 TPMT_KEYEDHASH_SCHEME *out)
2575 {
2576 json_object *jso2;
2577 TSS2_RC r;
2578 LOG_TRACE("call");
2579 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2580
2581 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
2582 LOG_ERROR("Bad value");
2583 return TSS2_FAPI_RC_BAD_VALUE;
2584 }
2585 r = ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_deserialize(jso2, &out->scheme);
2586 return_if_error(r, "BAD VALUE");
2587 if (out->scheme != TPM2_ALG_NULL) {
2588 if (!ifapi_get_sub_object(jso, "details", &jso2)) {
2589 LOG_ERROR("BAD VALUE");
2590 return TSS2_FAPI_RC_BAD_VALUE;
2591 }
2592 r = ifapi_json_TPMU_SCHEME_KEYEDHASH_deserialize(out->scheme, jso2,
2593 &out->details);
2594 return_if_error(r, "BAD VALUE");
2595 }
2596
2597 LOG_TRACE("true");
2598 return TSS2_RC_SUCCESS;
2599 }
2600
2601 /*** Table 148 - Definition of Types for RSA Signature Schemes ***/
2602
2603 /** Deserialize a TPMS_SIG_SCHEME_RSASSA json object.
2604 *
2605 * @param[in] jso the json object to be deserialized.
2606 * @param[out] out the deserialzed binary object.
2607 * @retval TSS2_RC_SUCCESS if the function call was a success.
2608 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2609 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2610 */
2611 TSS2_RC
2612 ifapi_json_TPMS_SIG_SCHEME_RSASSA_deserialize(json_object *jso,
2613 TPMS_SIG_SCHEME_RSASSA *out)
2614 {
2615 LOG_TRACE("call");
2616 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2617 }
2618
2619 /** Deserialize a TPMS_SIG_SCHEME_RSAPSS json object.
2620 *
2621 * @param[in] jso the json object to be deserialized.
2622 * @param[out] out the deserialzed binary object.
2623 * @retval TSS2_RC_SUCCESS if the function call was a success.
2624 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2625 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2626 */
2627 TSS2_RC
2628 ifapi_json_TPMS_SIG_SCHEME_RSAPSS_deserialize(json_object *jso,
2629 TPMS_SIG_SCHEME_RSAPSS *out)
2630 {
2631 LOG_TRACE("call");
2632 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2633 }
2634
2635 /*** Table 149 - Definition of Types for ECC Signature Schemes ***/
2636
2637 /** Deserialize a TPMS_SIG_SCHEME_ECDSA json object.
2638 *
2639 * @param[in] jso the json object to be deserialized.
2640 * @param[out] out the deserialzed binary object.
2641 * @retval TSS2_RC_SUCCESS if the function call was a success.
2642 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2643 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2644 */
2645 TSS2_RC
2646 ifapi_json_TPMS_SIG_SCHEME_ECDSA_deserialize(json_object *jso,
2647 TPMS_SIG_SCHEME_ECDSA *out)
2648 {
2649 LOG_TRACE("call");
2650 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2651 }
2652
2653 /** Deserialize a TPMS_SIG_SCHEME_SM2 json object.
2654 *
2655 * @param[in] jso the json object to be deserialized.
2656 * @param[out] out the deserialzed binary object.
2657 * @retval TSS2_RC_SUCCESS if the function call was a success.
2658 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2659 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2660 */
2661 TSS2_RC
2662 ifapi_json_TPMS_SIG_SCHEME_SM2_deserialize(json_object *jso,
2663 TPMS_SIG_SCHEME_SM2 *out)
2664 {
2665 LOG_TRACE("call");
2666 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2667 }
2668
2669 /** Deserialize a TPMS_SIG_SCHEME_ECSCHNORR json object.
2670 *
2671 * @param[in] jso the json object to be deserialized.
2672 * @param[out] out the deserialzed binary object.
2673 * @retval TSS2_RC_SUCCESS if the function call was a success.
2674 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2675 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2676 */
2677 TSS2_RC
2678 ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_deserialize(json_object *jso,
2679 TPMS_SIG_SCHEME_ECSCHNORR *out)
2680 {
2681 LOG_TRACE("call");
2682 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2683 }
2684
2685 /** Deserialize a TPMS_SIG_SCHEME_ECDAA json object.
2686 *
2687 * @param[in] jso the json object to be deserialized.
2688 * @param[out] out the deserialzed binary object.
2689 * @retval TSS2_RC_SUCCESS if the function call was a success.
2690 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2691 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2692 */
2693 TSS2_RC
2694 ifapi_json_TPMS_SIG_SCHEME_ECDAA_deserialize(json_object *jso,
2695 TPMS_SIG_SCHEME_ECDAA *out)
2696 {
2697 LOG_TRACE("call");
2698 return ifapi_json_TPMS_SCHEME_ECDAA_deserialize(jso, out);
2699 }
2700
2701 /** Deserialize a TPMU_SIG_SCHEME json object.
2702 *
2703 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
2704 * @param[in] selector The type the signature scheme.
2705 * @param[in] jso the json object to be deserialized.
2706 * @param[out] out the deserialzed binary object.
2707 * @retval TSS2_RC_SUCCESS if the function call was a success.
2708 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2709 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2710 */
2711 TSS2_RC
2712 ifapi_json_TPMU_SIG_SCHEME_deserialize(
2713 UINT32 selector,
2714 json_object *jso,
2715 TPMU_SIG_SCHEME *out)
2716 {
2717 LOG_TRACE("call");
2718 switch (selector) {
2719 case TPM2_ALG_RSASSA:
2720 return ifapi_json_TPMS_SIG_SCHEME_RSASSA_deserialize(jso, &out->rsassa);
2721 case TPM2_ALG_RSAPSS:
2722 return ifapi_json_TPMS_SIG_SCHEME_RSAPSS_deserialize(jso, &out->rsapss);
2723 case TPM2_ALG_ECDSA:
2724 return ifapi_json_TPMS_SIG_SCHEME_ECDSA_deserialize(jso, &out->ecdsa);
2725 case TPM2_ALG_ECDAA:
2726 return ifapi_json_TPMS_SIG_SCHEME_ECDAA_deserialize(jso, &out->ecdaa);
2727 case TPM2_ALG_SM2:
2728 return ifapi_json_TPMS_SIG_SCHEME_SM2_deserialize(jso, &out->sm2);
2729 case TPM2_ALG_ECSCHNORR:
2730 return ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_deserialize(jso, &out->ecschnorr);
2731 case TPM2_ALG_HMAC:
2732 return ifapi_json_TPMS_SCHEME_HMAC_deserialize(jso, &out->hmac);
2733
2734 case TPM2_ALG_NULL: {
2735 return TSS2_RC_SUCCESS;
2736 }
2737 default:
2738 LOG_TRACE("false");
2739 return TSS2_FAPI_RC_BAD_VALUE;
2740 };
2741 }
2742
2743 /** Deserialize a TPMT_SIG_SCHEME json object.
2744 *
2745 * @param[in] jso the json object to be deserialized.
2746 * @param[out] out the deserialzed binary object.
2747 * @retval TSS2_RC_SUCCESS if the function call was a success.
2748 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2749 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2750 */
2751 TSS2_RC
2752 ifapi_json_TPMT_SIG_SCHEME_deserialize(json_object *jso, TPMT_SIG_SCHEME *out)
2753 {
2754 json_object *jso2;
2755 TSS2_RC r;
2756 LOG_TRACE("call");
2757 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2758
2759 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
2760 LOG_ERROR("Bad value");
2761 return TSS2_FAPI_RC_BAD_VALUE;
2762 }
2763 r = ifapi_json_TPMI_ALG_SIG_SCHEME_deserialize(jso2, &out->scheme);
2764 return_if_error(r, "BAD VALUE");
2765 if (out->scheme != TPM2_ALG_NULL) {
2766 if (!ifapi_get_sub_object(jso, "details", &jso2)) {
2767 LOG_ERROR("BAD VALUE");
2768 return TSS2_FAPI_RC_BAD_VALUE;
2769 }
2770 r = ifapi_json_TPMU_SIG_SCHEME_deserialize(out->scheme, jso2, &out->details);
2771 return_if_error(r, "BAD VALUE");
2772 }
2773
2774 LOG_TRACE("true");
2775 return TSS2_RC_SUCCESS;
2776 }
2777
2778 /*** Table 152 - Definition of Types for Encryption Schemes ***/
2779
2780 /** Deserialize a TPMS_ENC_SCHEME_OAEP json object.
2781 *
2782 * @param[in] jso the json object to be deserialized.
2783 * @param[out] out the deserialzed binary object.
2784 * @retval TSS2_RC_SUCCESS if the function call was a success.
2785 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2786 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2787 */
2788 TSS2_RC
2789 ifapi_json_TPMS_ENC_SCHEME_OAEP_deserialize(json_object *jso,
2790 TPMS_ENC_SCHEME_OAEP *out)
2791 {
2792 LOG_TRACE("call");
2793 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2794 }
2795
2796 /** Deserialize a TPMS_ENC_SCHEME_RSAES json object.
2797 *
2798 * @param[in] jso the json object to be deserialized.
2799 * @param[out] out the deserialzed binary object.
2800 * @retval TSS2_RC_SUCCESS if the function call was a success.
2801 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2802 */
2803 TSS2_RC
2804 ifapi_json_TPMS_ENC_SCHEME_RSAES_deserialize(json_object *jso,
2805 TPMS_ENC_SCHEME_RSAES *out)
2806 {
2807 LOG_TRACE("call");
2808 return ifapi_json_TPMS_EMPTY_deserialize(jso, out);
2809 }
2810
2811 /*** Table 153 - Definition of Types for ECC Key Exchange ***/
2812
2813 /** Deserialize a TPMS_KEY_SCHEME_ECDH json object.
2814 *
2815 * @param[in] jso the json object to be deserialized.
2816 * @param[out] out the deserialzed binary object.
2817 * @retval TSS2_RC_SUCCESS if the function call was a success.
2818 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2819 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2820 */
2821 TSS2_RC
2822 ifapi_json_TPMS_KEY_SCHEME_ECDH_deserialize(json_object *jso,
2823 TPMS_KEY_SCHEME_ECDH *out)
2824 {
2825 LOG_TRACE("call");
2826 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2827 }
2828
2829 /*** Table 154 - Definition of Types for KDF Schemes ***/
2830
2831 /** Deserialize a TPMS_SCHEME_MGF1 json object.
2832 *
2833 * @param[in] jso the json object to be deserialized.
2834 * @param[out] out the deserialzed binary object.
2835 * @retval TSS2_RC_SUCCESS if the function call was a success.
2836 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2837 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2838 */
2839 TSS2_RC
2840 ifapi_json_TPMS_SCHEME_MGF1_deserialize(json_object *jso, TPMS_SCHEME_MGF1 *out)
2841 {
2842 LOG_TRACE("call");
2843 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2844 }
2845
2846 /** Deserialize a TPMS_SCHEME_KDF1_SP800_56A json object.
2847 *
2848 * @param[in] jso the json object to be deserialized.
2849 * @param[out] out the deserialzed binary object.
2850 * @retval TSS2_RC_SUCCESS if the function call was a success.
2851 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2852 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2853 */
2854 TSS2_RC
2855 ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_deserialize(json_object *jso,
2856 TPMS_SCHEME_KDF1_SP800_56A *out)
2857 {
2858 LOG_TRACE("call");
2859 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2860 }
2861
2862 /** Deserialize a TPMS_SCHEME_KDF1_SP800_108 json object.
2863 *
2864 * @param[in] jso the json object to be deserialized.
2865 * @param[out] out the deserialzed binary object.
2866 * @retval TSS2_RC_SUCCESS if the function call was a success.
2867 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2868 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2869 */
2870 TSS2_RC
2871 ifapi_json_TPMS_SCHEME_KDF1_SP800_108_deserialize(json_object *jso,
2872 TPMS_SCHEME_KDF1_SP800_108 *out)
2873 {
2874 LOG_TRACE("call");
2875 return ifapi_json_TPMS_SCHEME_HASH_deserialize(jso, out);
2876 }
2877
2878 /** Deserialize a TPMU_KDF_SCHEME json object.
2879 *
2880 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
2881 * @param[in] selector The type the KDF scheme.
2882 * @param[in] jso the json object to be deserialized.
2883 * @param[out] out the deserialzed binary object.
2884 * @retval TSS2_RC_SUCCESS if the function call was a success.
2885 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2886 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2887 */
2888 TSS2_RC
2889 ifapi_json_TPMU_KDF_SCHEME_deserialize(
2890 UINT32 selector,
2891 json_object *jso,
2892 TPMU_KDF_SCHEME *out)
2893 {
2894 LOG_TRACE("call");
2895 switch (selector) {
2896 case TPM2_ALG_MGF1:
2897 return ifapi_json_TPMS_SCHEME_MGF1_deserialize(jso, &out->mgf1);
2898 case TPM2_ALG_KDF1_SP800_56A:
2899 return ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_deserialize(jso,
2900 &out->kdf1_sp800_56a);
2901 case TPM2_ALG_KDF1_SP800_108:
2902 return ifapi_json_TPMS_SCHEME_KDF1_SP800_108_deserialize(jso,
2903 &out->kdf1_sp800_108);
2904
2905 case TPM2_ALG_NULL: {
2906 return TSS2_RC_SUCCESS;
2907 }
2908 default:
2909 LOG_TRACE("false");
2910 return TSS2_FAPI_RC_BAD_VALUE;
2911 };
2912 }
2913
2914 /** Deserialize a TPMT_KDF_SCHEME json object.
2915 *
2916 * @param[in] jso the json object to be deserialized.
2917 * @param[out] out the deserialzed binary object.
2918 * @retval TSS2_RC_SUCCESS if the function call was a success.
2919 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2920 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2921 */
2922 TSS2_RC
2923 ifapi_json_TPMT_KDF_SCHEME_deserialize(json_object *jso, TPMT_KDF_SCHEME *out)
2924 {
2925 json_object *jso2;
2926 TSS2_RC r;
2927 LOG_TRACE("call");
2928 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2929
2930 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
2931 LOG_ERROR("Bad value");
2932 return TSS2_FAPI_RC_BAD_VALUE;
2933 }
2934 r = ifapi_json_TPMI_ALG_KDF_deserialize(jso2, &out->scheme);
2935 return_if_error(r, "BAD VALUE");
2936 if (out->scheme != TPM2_ALG_NULL) {
2937 if (!ifapi_get_sub_object(jso, "details", &jso2)) {
2938 LOG_ERROR("BAD VALUE");
2939 return TSS2_FAPI_RC_BAD_VALUE;
2940 }
2941 r = ifapi_json_TPMU_KDF_SCHEME_deserialize(out->scheme, jso2, &out->details);
2942 return_if_error(r, "BAD VALUE");
2943 }
2944
2945 LOG_TRACE("true");
2946 return TSS2_RC_SUCCESS;
2947 }
2948
2949 /** Deserialize a TPMU_ASYM_SCHEME json object.
2950 *
2951 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
2952 * @param[in] jso the json object to be deserialized.
2953 * @param[in] selector The type the scheme.
2954 * @param[out] out the deserialzed binary object.
2955 * @retval TSS2_RC_SUCCESS if the function call was a success.
2956 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
2957 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2958 */
2959 TSS2_RC
2960 ifapi_json_TPMU_ASYM_SCHEME_deserialize(
2961 UINT32 selector,
2962 json_object *jso,
2963 TPMU_ASYM_SCHEME *out)
2964 {
2965 LOG_TRACE("call");
2966 switch (selector) {
2967 case TPM2_ALG_ECDH:
2968 return ifapi_json_TPMS_KEY_SCHEME_ECDH_deserialize(jso, &out->ecdh);
2969 case TPM2_ALG_RSASSA:
2970 return ifapi_json_TPMS_SIG_SCHEME_RSASSA_deserialize(jso, &out->rsassa);
2971 case TPM2_ALG_RSAPSS:
2972 return ifapi_json_TPMS_SIG_SCHEME_RSAPSS_deserialize(jso, &out->rsapss);
2973 case TPM2_ALG_ECDSA:
2974 return ifapi_json_TPMS_SIG_SCHEME_ECDSA_deserialize(jso, &out->ecdsa);
2975 case TPM2_ALG_ECDAA:
2976 return ifapi_json_TPMS_SIG_SCHEME_ECDAA_deserialize(jso, &out->ecdaa);
2977 case TPM2_ALG_SM2:
2978 return ifapi_json_TPMS_SIG_SCHEME_SM2_deserialize(jso, &out->sm2);
2979 case TPM2_ALG_ECSCHNORR:
2980 return ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_deserialize(jso, &out->ecschnorr);
2981 case TPM2_ALG_RSAES:
2982 return ifapi_json_TPMS_ENC_SCHEME_RSAES_deserialize(jso, &out->rsaes);
2983 case TPM2_ALG_OAEP:
2984 return ifapi_json_TPMS_ENC_SCHEME_OAEP_deserialize(jso, &out->oaep);
2985
2986 case TPM2_ALG_NULL: {
2987 return TSS2_RC_SUCCESS;
2988 }
2989 default:
2990 LOG_TRACE("false");
2991 return TSS2_FAPI_RC_BAD_VALUE;
2992 };
2993 }
2994
2995 /** Deserialize a TPMI_ALG_RSA_SCHEME json object.
2996 *
2997 * @param[in] jso the json object to be deserialized.
2998 * @param[out] out the deserialzed binary object.
2999 * @retval TSS2_RC_SUCCESS if the function call was a success.
3000 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3001 */
3002 TSS2_RC
3003 ifapi_json_TPMI_ALG_RSA_SCHEME_deserialize(json_object *jso,
3004 TPMI_ALG_RSA_SCHEME *out)
3005 {
3006 SUBTYPE_FILTER(TPMI_ALG_RSA_SCHEME, TPM2_ALG_ID,
3007 TPM2_ALG_RSAES, TPM2_ALG_OAEP, TPM2_ALG_RSASSA, TPM2_ALG_RSAPSS, TPM2_ALG_NULL);
3008 }
3009
3010 /** Deserialize a TPMT_RSA_SCHEME json object.
3011 *
3012 * @param[in] jso the json object to be deserialized.
3013 * @param[out] out the deserialzed binary object.
3014 * @retval TSS2_RC_SUCCESS if the function call was a success.
3015 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3016 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3017 */
3018 TSS2_RC
3019 ifapi_json_TPMT_RSA_SCHEME_deserialize(json_object *jso, TPMT_RSA_SCHEME *out)
3020 {
3021 json_object *jso2;
3022 TSS2_RC r;
3023 LOG_TRACE("call");
3024 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3025
3026 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
3027 LOG_ERROR("Bad value");
3028 return TSS2_FAPI_RC_BAD_VALUE;
3029 }
3030 r = ifapi_json_TPMI_ALG_RSA_SCHEME_deserialize(jso2, &out->scheme);
3031 return_if_error(r, "BAD VALUE");
3032 if (out->scheme != TPM2_ALG_NULL) {
3033 if (!ifapi_get_sub_object(jso, "details", &jso2)) {
3034 LOG_ERROR("BAD VALUE");
3035 return TSS2_FAPI_RC_BAD_VALUE;
3036 }
3037 r = ifapi_json_TPMU_ASYM_SCHEME_deserialize(out->scheme, jso2, &out->details);
3038 return_if_error(r, "BAD VALUE");
3039 }
3040
3041 LOG_TRACE("true");
3042 return TSS2_RC_SUCCESS;
3043 }
3044
3045 /** Deserialize a TPMI_ALG_RSA_DECRYPT json object.
3046 *
3047 * @param[in] jso the json object to be deserialized.
3048 * @param[out] out the deserialzed binary object.
3049 * @retval TSS2_RC_SUCCESS if the function call was a success.
3050 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3051 */
3052 TSS2_RC
3053 ifapi_json_TPMI_ALG_RSA_DECRYPT_deserialize(json_object *jso,
3054 TPMI_ALG_RSA_DECRYPT *out)
3055 {
3056 SUBTYPE_FILTER(TPMI_ALG_RSA_DECRYPT, TPM2_ALG_ID,
3057 TPM2_ALG_RSAES, TPM2_ALG_OAEP, TPM2_ALG_NULL);
3058 }
3059
3060 /** Deserialize a TPMT_RSA_DECRYPT json object.
3061 *
3062 * @param[in] jso the json object to be deserialized.
3063 * @param[out] out the deserialzed binary object.
3064 * @retval TSS2_RC_SUCCESS if the function call was a success.
3065 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3066 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3067 */
3068 TSS2_RC
3069 ifapi_json_TPMT_RSA_DECRYPT_deserialize(json_object *jso,
3070 TPMT_RSA_DECRYPT *out)
3071 {
3072 json_object *jso2;
3073 TSS2_RC r;
3074 LOG_TRACE("call");
3075 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3076
3077 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
3078 LOG_ERROR("Bad value");
3079 return TSS2_FAPI_RC_BAD_VALUE;
3080 }
3081 r = ifapi_json_TPMI_ALG_RSA_DECRYPT_deserialize(jso2, &out->scheme);
3082 return_if_error(r, "BAD VALUE");
3083 if (out->scheme != TPM2_ALG_NULL) {
3084 if (!ifapi_get_sub_object(jso, "details", &jso2)) {
3085 LOG_ERROR("BAD VALUE");
3086 return TSS2_FAPI_RC_BAD_VALUE;
3087 }
3088 r = ifapi_json_TPMU_ASYM_SCHEME_deserialize(out->scheme, jso2, &out->details);
3089 return_if_error(r, "BAD VALUE");
3090 }
3091
3092 LOG_TRACE("true");
3093 return TSS2_RC_SUCCESS;
3094 }
3095
3096 /** Deserialize a TPM2B_PUBLIC_KEY_RSA json object.
3097 *
3098 * @param[in] jso the json object to be deserialized.
3099 * @param[out] out the deserialzed binary object.
3100 * @retval TSS2_RC_SUCCESS if the function call was a success.
3101 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3102 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3103 */
3104 TSS2_RC
3105 ifapi_json_TPM2B_PUBLIC_KEY_RSA_deserialize(json_object *jso,
3106 TPM2B_PUBLIC_KEY_RSA *out)
3107 {
3108 TSS2_RC r;
3109 LOG_TRACE("call");
3110 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3111
3112 UINT16 size = 0;
3113 r = ifapi_json_byte_deserialize(jso, TPM2_MAX_RSA_KEY_BYTES,
3114 (BYTE *)&out->buffer, &size);
3115 return_if_error(r, "byte serialize");
3116
3117 out->size = size;
3118 return r;
3119 LOG_TRACE("true");
3120 return TSS2_RC_SUCCESS;
3121 }
3122
3123 /** Deserialize a TPMI_RSA_KEY_BITS json object.
3124 *
3125 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
3126 * the function.
3127 */
3128 TSS2_RC
3129 ifapi_json_TPMI_RSA_KEY_BITS_deserialize(json_object *jso,
3130 TPMI_RSA_KEY_BITS *out)
3131 {
3132 SUBTYPE_FILTER(TPMI_RSA_KEY_BITS, UINT16,
3133 1024, 2048);
3134 }
3135
3136 /** Deserialize a TPM2B_ECC_PARAMETER json object.
3137 *
3138 * @param[in] jso the json object to be deserialized.
3139 * @param[out] out the deserialzed binary object.
3140 * @retval TSS2_RC_SUCCESS if the function call was a success.
3141 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3142 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3143 */
3144 TSS2_RC
3145 ifapi_json_TPM2B_ECC_PARAMETER_deserialize(json_object *jso,
3146 TPM2B_ECC_PARAMETER *out)
3147 {
3148 TSS2_RC r;
3149 LOG_TRACE("call");
3150 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3151
3152 UINT16 size = 0;
3153 r = ifapi_json_byte_deserialize(jso, TPM2_MAX_ECC_KEY_BYTES,
3154 (BYTE *)&out->buffer, &size);
3155 return_if_error(r, "byte serialize");
3156
3157 out->size = size;
3158 return r;
3159 LOG_TRACE("true");
3160 return TSS2_RC_SUCCESS;
3161 }
3162
3163 /** Deserialize a TPMS_ECC_POINT json object.
3164 *
3165 * @param[in] jso the json object to be deserialized.
3166 * @param[out] out the deserialzed binary object.
3167 * @retval TSS2_RC_SUCCESS if the function call was a success.
3168 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3169 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3170 */
3171 TSS2_RC
3172 ifapi_json_TPMS_ECC_POINT_deserialize(json_object *jso, TPMS_ECC_POINT *out)
3173 {
3174 json_object *jso2;
3175 TSS2_RC r;
3176 LOG_TRACE("call");
3177 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3178
3179 if (!ifapi_get_sub_object(jso, "x", &jso2)) {
3180 LOG_ERROR("Bad value");
3181 return TSS2_FAPI_RC_BAD_VALUE;
3182 }
3183 r = ifapi_json_TPM2B_ECC_PARAMETER_deserialize(jso2, &out->x);
3184 return_if_error(r, "BAD VALUE");
3185
3186 if (!ifapi_get_sub_object(jso, "y", &jso2)) {
3187 LOG_ERROR("Bad value");
3188 return TSS2_FAPI_RC_BAD_VALUE;
3189 }
3190 r = ifapi_json_TPM2B_ECC_PARAMETER_deserialize(jso2, &out->y);
3191 return_if_error(r, "BAD VALUE");
3192 LOG_TRACE("true");
3193 return TSS2_RC_SUCCESS;
3194 }
3195
3196 /** Deserialize a TPMI_ALG_ECC_SCHEME json object.
3197 *
3198 * @param[in] jso the json object to be deserialized.
3199 * @param[out] out the deserialzed binary object.
3200 * @retval TSS2_RC_SUCCESS if the function call was a success.
3201 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3202 */
3203 TSS2_RC
3204 ifapi_json_TPMI_ALG_ECC_SCHEME_deserialize(json_object *jso,
3205 TPMI_ALG_ECC_SCHEME *out)
3206 {
3207 SUBTYPE_FILTER(TPMI_ALG_ECC_SCHEME, TPM2_ALG_ID,
3208 TPM2_ALG_ECDSA, TPM2_ALG_ECDAA, TPM2_ALG_SM2, TPM2_ALG_ECSCHNORR,
3209 TPM2_ALG_ECDH, TPM2_ALG_NULL);
3210 }
3211
3212 /** Deserialize a TPMI_ECC_CURVE json object.
3213 *
3214 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
3215 * the function.
3216 */
3217 TSS2_RC
3218 ifapi_json_TPMI_ECC_CURVE_deserialize(json_object *jso, TPMI_ECC_CURVE *out)
3219 {
3220 SUBTYPE_FILTER(TPMI_ECC_CURVE, TPM2_ECC_CURVE,
3221 TPM2_ECC_NONE, TPM2_ECC_NIST_P192, TPM2_ECC_NIST_P224, TPM2_ECC_NIST_P256,
3222 TPM2_ECC_NIST_P384, TPM2_ECC_NIST_P521, TPM2_ECC_BN_P256, TPM2_ECC_BN_P638,
3223 TPM2_ECC_SM2_P256);
3224 }
3225
3226 /** Deserialize a TPMT_ECC_SCHEME json object.
3227 *
3228 * @param[in] jso the json object to be deserialized.
3229 * @param[out] out the deserialzed binary object.
3230 * @retval TSS2_RC_SUCCESS if the function call was a success.
3231 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3232 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3233 */
3234 TSS2_RC
3235 ifapi_json_TPMT_ECC_SCHEME_deserialize(json_object *jso, TPMT_ECC_SCHEME *out)
3236 {
3237 json_object *jso2;
3238 TSS2_RC r;
3239 LOG_TRACE("call");
3240 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3241
3242 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
3243 LOG_ERROR("Bad value");
3244 return TSS2_FAPI_RC_BAD_VALUE;
3245 }
3246 r = ifapi_json_TPMI_ALG_ECC_SCHEME_deserialize(jso2, &out->scheme);
3247 return_if_error(r, "BAD VALUE");
3248 if (out->scheme != TPM2_ALG_NULL) {
3249 if (!ifapi_get_sub_object(jso, "details", &jso2)) {
3250 LOG_ERROR("BAD VALUE");
3251 return TSS2_FAPI_RC_BAD_VALUE;
3252 }
3253 r = ifapi_json_TPMU_ASYM_SCHEME_deserialize(out->scheme, jso2, &out->details);
3254 return_if_error(r, "BAD VALUE");
3255 }
3256
3257 LOG_TRACE("true");
3258 return TSS2_RC_SUCCESS;
3259 }
3260
3261 /** Deserialize a TPMS_SIGNATURE_RSA json object.
3262 *
3263 * @param[in] jso the json object to be deserialized.
3264 * @param[out] out the deserialzed binary object.
3265 * @retval TSS2_RC_SUCCESS if the function call was a success.
3266 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3267 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3268 */
3269 TSS2_RC
3270 ifapi_json_TPMS_SIGNATURE_RSA_deserialize(json_object *jso,
3271 TPMS_SIGNATURE_RSA *out)
3272 {
3273 json_object *jso2;
3274 TSS2_RC r;
3275 LOG_TRACE("call");
3276 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3277
3278 if (!ifapi_get_sub_object(jso, "hash", &jso2)) {
3279 LOG_ERROR("Bad value");
3280 return TSS2_FAPI_RC_BAD_VALUE;
3281 }
3282 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->hash);
3283 return_if_error(r, "BAD VALUE");
3284
3285 if (!ifapi_get_sub_object(jso, "sig", &jso2)) {
3286 LOG_ERROR("Bad value");
3287 return TSS2_FAPI_RC_BAD_VALUE;
3288 }
3289 r = ifapi_json_TPM2B_PUBLIC_KEY_RSA_deserialize(jso2, &out->sig);
3290 return_if_error(r, "BAD VALUE");
3291 LOG_TRACE("true");
3292 return TSS2_RC_SUCCESS;
3293 }
3294
3295 /*** Table 175 - Definition of Types for Signature ***/
3296
3297 /** Deserialize a TPMS_SIGNATURE_RSASSA json object.
3298 *
3299 * @param[in] jso the json object to be deserialized.
3300 * @param[out] out the deserialzed binary object.
3301 * @retval TSS2_RC_SUCCESS if the function call was a success.
3302 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3303 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3304 */
3305 TSS2_RC
3306 ifapi_json_TPMS_SIGNATURE_RSASSA_deserialize(json_object *jso,
3307 TPMS_SIGNATURE_RSASSA *out)
3308 {
3309 LOG_TRACE("call");
3310 return ifapi_json_TPMS_SIGNATURE_RSA_deserialize(jso, out);
3311 }
3312
3313 /** Deserialize a TPMS_SIGNATURE_RSAPSS json object.
3314 *
3315 * @param[in] jso the json object to be deserialized.
3316 * @param[out] out the deserialzed binary object.
3317 * @retval TSS2_RC_SUCCESS if the function call was a success.
3318 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3319 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3320 */
3321 TSS2_RC
3322 ifapi_json_TPMS_SIGNATURE_RSAPSS_deserialize(json_object *jso,
3323 TPMS_SIGNATURE_RSAPSS *out)
3324 {
3325 LOG_TRACE("call");
3326 return ifapi_json_TPMS_SIGNATURE_RSA_deserialize(jso, out);
3327 }
3328
3329 /** Deserialize a TPMS_SIGNATURE_ECC json object.
3330 *
3331 * @param[in] jso the json object to be deserialized.
3332 * @param[out] out the deserialzed binary object.
3333 * @retval TSS2_RC_SUCCESS if the function call was a success.
3334 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3335 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3336 */
3337 TSS2_RC
3338 ifapi_json_TPMS_SIGNATURE_ECC_deserialize(json_object *jso,
3339 TPMS_SIGNATURE_ECC *out)
3340 {
3341 json_object *jso2;
3342 TSS2_RC r;
3343 LOG_TRACE("call");
3344 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3345
3346 if (!ifapi_get_sub_object(jso, "hash", &jso2)) {
3347 LOG_ERROR("Bad value");
3348 return TSS2_FAPI_RC_BAD_VALUE;
3349 }
3350 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->hash);
3351 return_if_error(r, "BAD VALUE");
3352
3353 if (!ifapi_get_sub_object(jso, "signatureR", &jso2)) {
3354 LOG_ERROR("Bad value");
3355 return TSS2_FAPI_RC_BAD_VALUE;
3356 }
3357 r = ifapi_json_TPM2B_ECC_PARAMETER_deserialize(jso2, &out->signatureR);
3358 return_if_error(r, "BAD VALUE");
3359
3360 if (!ifapi_get_sub_object(jso, "signatureS", &jso2)) {
3361 LOG_ERROR("Bad value");
3362 return TSS2_FAPI_RC_BAD_VALUE;
3363 }
3364 r = ifapi_json_TPM2B_ECC_PARAMETER_deserialize(jso2, &out->signatureS);
3365 return_if_error(r, "BAD VALUE");
3366 LOG_TRACE("true");
3367 return TSS2_RC_SUCCESS;
3368 }
3369
3370 /*** Table 177 - Definition of Types for TPMS_SIGNATURE_ECC ***/
3371
3372 /** Deserialize a TPMS_SIGNATURE_ECDSA json object.
3373 *
3374 * @param[in] jso the json object to be deserialized.
3375 * @param[out] out the deserialzed binary object.
3376 * @retval TSS2_RC_SUCCESS if the function call was a success.
3377 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3378 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3379 */
3380 TSS2_RC
3381 ifapi_json_TPMS_SIGNATURE_ECDSA_deserialize(json_object *jso,
3382 TPMS_SIGNATURE_ECDSA *out)
3383 {
3384 LOG_TRACE("call");
3385 return ifapi_json_TPMS_SIGNATURE_ECC_deserialize(jso, out);
3386 }
3387
3388 /** Deserialize a TPMS_SIGNATURE_ECDAA json object.
3389 *
3390 * @param[in] jso the json object to be deserialized.
3391 * @param[out] out the deserialzed binary object.
3392 * @retval TSS2_RC_SUCCESS if the function call was a success.
3393 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3394 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3395 */
3396 TSS2_RC
3397 ifapi_json_TPMS_SIGNATURE_ECDAA_deserialize(json_object *jso,
3398 TPMS_SIGNATURE_ECDAA *out)
3399 {
3400 LOG_TRACE("call");
3401 return ifapi_json_TPMS_SIGNATURE_ECC_deserialize(jso, out);
3402 }
3403
3404 /** Deserialize a TPMS_SIGNATURE_SM2 json object.
3405 *
3406 * @param[in] jso the json object to be deserialized.
3407 * @param[out] out the deserialzed binary object.
3408 * @retval TSS2_RC_SUCCESS if the function call was a success.
3409 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3410 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3411 */
3412 TSS2_RC
3413 ifapi_json_TPMS_SIGNATURE_SM2_deserialize(json_object *jso,
3414 TPMS_SIGNATURE_SM2 *out)
3415 {
3416 LOG_TRACE("call");
3417 return ifapi_json_TPMS_SIGNATURE_ECC_deserialize(jso, out);
3418 }
3419
3420 /** Deserialize a TPMS_SIGNATURE_ECSCHNORR json object.
3421 *
3422 * @param[in] jso the json object to be deserialized.
3423 * @param[out] out the deserialzed binary object.
3424 * @retval TSS2_RC_SUCCESS if the function call was a success.
3425 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3426 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3427 */
3428 TSS2_RC
3429 ifapi_json_TPMS_SIGNATURE_ECSCHNORR_deserialize(json_object *jso,
3430 TPMS_SIGNATURE_ECSCHNORR *out)
3431 {
3432 LOG_TRACE("call");
3433 return ifapi_json_TPMS_SIGNATURE_ECC_deserialize(jso, out);
3434 }
3435
3436 /** Deserialize a TPMU_SIGNATURE json object.
3437 *
3438 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
3439 * @param[in] selector The type the signature.
3440 * @param[in] jso the json object to be deserialized.
3441 * @param[out] out the deserialzed binary object.
3442 * @retval TSS2_RC_SUCCESS if the function call was a success.
3443 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3444 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3445 */
3446 TSS2_RC
3447 ifapi_json_TPMU_SIGNATURE_deserialize(
3448 UINT32 selector,
3449 json_object *jso,
3450 TPMU_SIGNATURE *out)
3451 {
3452 LOG_TRACE("call");
3453 switch (selector) {
3454 case TPM2_ALG_RSASSA:
3455 return ifapi_json_TPMS_SIGNATURE_RSASSA_deserialize(jso, &out->rsassa);
3456 case TPM2_ALG_RSAPSS:
3457 return ifapi_json_TPMS_SIGNATURE_RSAPSS_deserialize(jso, &out->rsapss);
3458 case TPM2_ALG_ECDSA:
3459 return ifapi_json_TPMS_SIGNATURE_ECDSA_deserialize(jso, &out->ecdsa);
3460 case TPM2_ALG_ECDAA:
3461 return ifapi_json_TPMS_SIGNATURE_ECDAA_deserialize(jso, &out->ecdaa);
3462 case TPM2_ALG_SM2:
3463 return ifapi_json_TPMS_SIGNATURE_SM2_deserialize(jso, &out->sm2);
3464 case TPM2_ALG_ECSCHNORR:
3465 return ifapi_json_TPMS_SIGNATURE_ECSCHNORR_deserialize(jso, &out->ecschnorr);
3466 case TPM2_ALG_HMAC:
3467 return ifapi_json_TPMT_HA_deserialize(jso, &out->hmac);
3468
3469 case TPM2_ALG_NULL: {
3470 return TSS2_RC_SUCCESS;
3471 }
3472 default:
3473 LOG_TRACE("false");
3474 return TSS2_FAPI_RC_BAD_VALUE;
3475 };
3476 }
3477
3478 /** Deserialize a TPMT_SIGNATURE json object.
3479 *
3480 * @param[in] jso the json object to be deserialized.
3481 * @param[out] out the deserialzed binary object.
3482 * @retval TSS2_RC_SUCCESS if the function call was a success.
3483 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3484 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3485 */
3486 TSS2_RC
3487 ifapi_json_TPMT_SIGNATURE_deserialize(json_object *jso, TPMT_SIGNATURE *out)
3488 {
3489 json_object *jso2;
3490 TSS2_RC r;
3491 LOG_TRACE("call");
3492 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3493
3494 if (!ifapi_get_sub_object(jso, "sigAlg", &jso2)) {
3495 LOG_ERROR("Bad value");
3496 return TSS2_FAPI_RC_BAD_VALUE;
3497 }
3498 r = ifapi_json_TPMI_ALG_SIG_SCHEME_deserialize(jso2, &out->sigAlg);
3499 return_if_error(r, "BAD VALUE");
3500 if (out->sigAlg != TPM2_ALG_NULL) {
3501 if (!ifapi_get_sub_object(jso, "signature", &jso2)) {
3502 LOG_ERROR("BAD VALUE");
3503 return TSS2_FAPI_RC_BAD_VALUE;
3504 }
3505 r = ifapi_json_TPMU_SIGNATURE_deserialize(out->sigAlg, jso2, &out->signature);
3506 return_if_error(r, "BAD VALUE");
3507 }
3508
3509 LOG_TRACE("true");
3510 return TSS2_RC_SUCCESS;
3511 }
3512
3513 /** Deserialize a TPM2B_ENCRYPTED_SECRET json object.
3514 *
3515 * @param[in] jso the json object to be deserialized.
3516 * @param[out] out the deserialzed binary object.
3517 * @retval TSS2_RC_SUCCESS if the function call was a success.
3518 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3519 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3520 */
3521 TSS2_RC
3522 ifapi_json_TPM2B_ENCRYPTED_SECRET_deserialize(json_object *jso,
3523 TPM2B_ENCRYPTED_SECRET *out)
3524 {
3525 TSS2_RC r;
3526 LOG_TRACE("call");
3527 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3528
3529 UINT16 size = 0;
3530 r = ifapi_json_byte_deserialize(jso, sizeof(TPMU_ENCRYPTED_SECRET),
3531 (BYTE *)&out->secret, &size);
3532 return_if_error(r, "byte serialize");
3533
3534 out->size = size;
3535 return r;
3536 LOG_TRACE("true");
3537 return TSS2_RC_SUCCESS;
3538 }
3539
3540 /** Deserialize a TPMI_ALG_PUBLIC json object.
3541 *
3542 * @param[in] jso the json object to be deserialized.
3543 * @param[out] out the deserialzed binary object.
3544 * @retval TSS2_RC_SUCCESS if the function call was a success.
3545 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3546 */
3547 TSS2_RC
3548 ifapi_json_TPMI_ALG_PUBLIC_deserialize(json_object *jso, TPMI_ALG_PUBLIC *out)
3549 {
3550 SUBTYPE_FILTER(TPMI_ALG_PUBLIC, TPM2_ALG_ID,
3551 TPM2_ALG_RSA, TPM2_ALG_KEYEDHASH, TPM2_ALG_ECC, TPM2_ALG_SYMCIPHER, TPM2_ALG_NULL);
3552 }
3553
3554 /** Deserialize a TPMU_PUBLIC_ID json object.
3555 *
3556 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
3557 * @param[in] selector The type the public ID.
3558 * @param[in] jso the json object to be deserialized.
3559 * @param[out] out the deserialzed binary object.
3560 * @retval TSS2_RC_SUCCESS if the function call was a success.
3561 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3562 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3563 */
3564 TSS2_RC
3565 ifapi_json_TPMU_PUBLIC_ID_deserialize(
3566 UINT32 selector,
3567 json_object *jso,
3568 TPMU_PUBLIC_ID *out)
3569 {
3570 LOG_TRACE("call");
3571 switch (selector) {
3572 case TPM2_ALG_KEYEDHASH:
3573 return ifapi_json_TPM2B_DIGEST_deserialize(jso, &out->keyedHash);
3574 case TPM2_ALG_SYMCIPHER:
3575 return ifapi_json_TPM2B_DIGEST_deserialize(jso, &out->sym);
3576 case TPM2_ALG_RSA:
3577 return ifapi_json_TPM2B_PUBLIC_KEY_RSA_deserialize(jso, &out->rsa);
3578 case TPM2_ALG_ECC:
3579 return ifapi_json_TPMS_ECC_POINT_deserialize(jso, &out->ecc);
3580 default:
3581 LOG_TRACE("false");
3582 return TSS2_FAPI_RC_BAD_VALUE;
3583 };
3584 }
3585
3586 /** Deserialize a TPMS_KEYEDHASH_PARMS json object.
3587 *
3588 * @param[in] jso the json object to be deserialized.
3589 * @param[out] out the deserialzed binary object.
3590 * @retval TSS2_RC_SUCCESS if the function call was a success.
3591 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3592 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3593 */
3594 TSS2_RC
3595 ifapi_json_TPMS_KEYEDHASH_PARMS_deserialize(json_object *jso,
3596 TPMS_KEYEDHASH_PARMS *out)
3597 {
3598 json_object *jso2;
3599 TSS2_RC r;
3600 LOG_TRACE("call");
3601 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3602
3603 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
3604 LOG_ERROR("Bad value");
3605 return TSS2_FAPI_RC_BAD_VALUE;
3606 }
3607 r = ifapi_json_TPMT_KEYEDHASH_SCHEME_deserialize(jso2, &out->scheme);
3608 return_if_error(r, "BAD VALUE");
3609 LOG_TRACE("true");
3610 return TSS2_RC_SUCCESS;
3611 }
3612
3613 /** Deserialize a TPMS_RSA_PARMS json object.
3614 *
3615 * @param[in] jso the json object to be deserialized.
3616 * @param[out] out the deserialzed binary object.
3617 * @retval TSS2_RC_SUCCESS if the function call was a success.
3618 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3619 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3620 */
3621 TSS2_RC
3622 ifapi_json_TPMS_RSA_PARMS_deserialize(json_object *jso, TPMS_RSA_PARMS *out)
3623 {
3624 json_object *jso2;
3625 TSS2_RC r;
3626 LOG_TRACE("call");
3627 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3628
3629 if (!ifapi_get_sub_object(jso, "symmetric", &jso2)) {
3630 LOG_ERROR("Bad value");
3631 return TSS2_FAPI_RC_BAD_VALUE;
3632 }
3633 r = ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(jso2, &out->symmetric);
3634 return_if_error(r, "BAD VALUE");
3635
3636 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
3637 LOG_ERROR("Bad value");
3638 return TSS2_FAPI_RC_BAD_VALUE;
3639 }
3640 r = ifapi_json_TPMT_RSA_SCHEME_deserialize(jso2, &out->scheme);
3641 return_if_error(r, "BAD VALUE");
3642
3643 if (!ifapi_get_sub_object(jso, "keyBits", &jso2)) {
3644 LOG_ERROR("Bad value");
3645 return TSS2_FAPI_RC_BAD_VALUE;
3646 }
3647 r = ifapi_json_TPMI_RSA_KEY_BITS_deserialize(jso2, &out->keyBits);
3648 return_if_error(r, "BAD VALUE");
3649
3650 if (!ifapi_get_sub_object(jso, "exponent", &jso2)) {
3651 LOG_ERROR("Bad value");
3652 return TSS2_FAPI_RC_BAD_VALUE;
3653 }
3654 r = ifapi_json_UINT32_deserialize(jso2, &out->exponent);
3655 return_if_error(r, "BAD VALUE");
3656 LOG_TRACE("true");
3657 return TSS2_RC_SUCCESS;
3658 }
3659
3660 /** Deserialize a TPMS_ECC_PARMS json object.
3661 *
3662 * @param[in] jso the json object to be deserialized.
3663 * @param[out] out the deserialzed binary object.
3664 * @retval TSS2_RC_SUCCESS if the function call was a success.
3665 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3666 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3667 */
3668 TSS2_RC
3669 ifapi_json_TPMS_ECC_PARMS_deserialize(json_object *jso, TPMS_ECC_PARMS *out)
3670 {
3671 json_object *jso2;
3672 TSS2_RC r;
3673 LOG_TRACE("call");
3674 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3675
3676 if (!ifapi_get_sub_object(jso, "symmetric", &jso2)) {
3677 LOG_ERROR("Bad value");
3678 return TSS2_FAPI_RC_BAD_VALUE;
3679 }
3680 r = ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(jso2, &out->symmetric);
3681 return_if_error(r, "BAD VALUE");
3682
3683 if (!ifapi_get_sub_object(jso, "scheme", &jso2)) {
3684 LOG_ERROR("Bad value");
3685 return TSS2_FAPI_RC_BAD_VALUE;
3686 }
3687 r = ifapi_json_TPMT_ECC_SCHEME_deserialize(jso2, &out->scheme);
3688 return_if_error(r, "BAD VALUE");
3689
3690 if (!ifapi_get_sub_object(jso, "curveID", &jso2)) {
3691 LOG_ERROR("Bad value");
3692 return TSS2_FAPI_RC_BAD_VALUE;
3693 }
3694 r = ifapi_json_TPMI_ECC_CURVE_deserialize(jso2, &out->curveID);
3695 return_if_error(r, "BAD VALUE");
3696
3697 if (!ifapi_get_sub_object(jso, "kdf", &jso2)) {
3698 LOG_ERROR("Bad value");
3699 return TSS2_FAPI_RC_BAD_VALUE;
3700 }
3701 r = ifapi_json_TPMT_KDF_SCHEME_deserialize(jso2, &out->kdf);
3702 return_if_error(r, "BAD VALUE");
3703 LOG_TRACE("true");
3704 return TSS2_RC_SUCCESS;
3705 }
3706
3707 /** Deserialize a TPMU_PUBLIC_PARMS json object.
3708 *
3709 * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
3710 * @param[in] selector The type the public params.
3711 * @param[in] jso the json object to be deserialized.
3712 * @param[out] out the deserialzed binary object.
3713 * @retval TSS2_RC_SUCCESS if the function call was a success.
3714 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3715 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3716 */
3717 TSS2_RC
3718 ifapi_json_TPMU_PUBLIC_PARMS_deserialize(
3719 UINT32 selector,
3720 json_object *jso,
3721 TPMU_PUBLIC_PARMS *out)
3722 {
3723 LOG_TRACE("call");
3724 switch (selector) {
3725 case TPM2_ALG_KEYEDHASH:
3726 return ifapi_json_TPMS_KEYEDHASH_PARMS_deserialize(jso, &out->keyedHashDetail);
3727 case TPM2_ALG_SYMCIPHER:
3728 return ifapi_json_TPMS_SYMCIPHER_PARMS_deserialize(jso, &out->symDetail);
3729 case TPM2_ALG_RSA:
3730 return ifapi_json_TPMS_RSA_PARMS_deserialize(jso, &out->rsaDetail);
3731 case TPM2_ALG_ECC:
3732 return ifapi_json_TPMS_ECC_PARMS_deserialize(jso, &out->eccDetail);
3733 default:
3734 LOG_TRACE("false");
3735 return TSS2_FAPI_RC_BAD_VALUE;
3736 };
3737 }
3738
3739 /** Deserialize a TPMT_PUBLIC json object.
3740 *
3741 * @param[in] jso the json object to be deserialized.
3742 * @param[out] out the deserialzed binary object.
3743 * @retval TSS2_RC_SUCCESS if the function call was a success.
3744 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3745 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3746 */
3747 TSS2_RC
3748 ifapi_json_TPMT_PUBLIC_deserialize(json_object *jso, TPMT_PUBLIC *out)
3749 {
3750 json_object *jso2;
3751 TSS2_RC r;
3752 LOG_TRACE("call");
3753 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3754
3755 if (!ifapi_get_sub_object(jso, "type", &jso2)) {
3756 LOG_ERROR("Bad value");
3757 return TSS2_FAPI_RC_BAD_VALUE;
3758 }
3759 r = ifapi_json_TPMI_ALG_PUBLIC_deserialize(jso2, &out->type);
3760 return_if_error(r, "BAD VALUE");
3761
3762 if (!ifapi_get_sub_object(jso, "nameAlg", &jso2)) {
3763 LOG_ERROR("Bad value");
3764 return TSS2_FAPI_RC_BAD_VALUE;
3765 }
3766 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->nameAlg);
3767 return_if_error(r, "BAD VALUE");
3768
3769 if (!ifapi_get_sub_object(jso, "objectAttributes", &jso2)) {
3770 LOG_ERROR("Bad value");
3771 return TSS2_FAPI_RC_BAD_VALUE;
3772 }
3773 r = ifapi_json_TPMA_OBJECT_deserialize(jso2, &out->objectAttributes);
3774 return_if_error(r, "BAD VALUE");
3775
3776 if (!ifapi_get_sub_object(jso, "authPolicy", &jso2)) {
3777 LOG_ERROR("Bad value");
3778 return TSS2_FAPI_RC_BAD_VALUE;
3779 }
3780 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->authPolicy);
3781 return_if_error(r, "BAD VALUE");
3782 if (!ifapi_get_sub_object(jso, "parameters", &jso2)) {
3783 LOG_ERROR("BAD VALUE");
3784 return TSS2_FAPI_RC_BAD_VALUE;
3785 }
3786 r = ifapi_json_TPMU_PUBLIC_PARMS_deserialize(out->type, jso2, &out->parameters);
3787 return_if_error(r, "BAD VALUE");
3788
3789 if (!ifapi_get_sub_object(jso, "unique", &jso2)) {
3790 LOG_ERROR("BAD VALUE");
3791 return TSS2_FAPI_RC_BAD_VALUE;
3792 }
3793 r = ifapi_json_TPMU_PUBLIC_ID_deserialize(out->type, jso2, &out->unique);
3794 return_if_error(r, "BAD VALUE");
3795
3796 LOG_TRACE("true");
3797 return TSS2_RC_SUCCESS;
3798 }
3799
3800 /** Deserialize a TPM2B_PUBLIC json object.
3801 * @param[in] jso the json object to be deserialized.
3802 * @param[out] out the deserialzed binary object.
3803 * @retval TSS2_RC_SUCCESS if the function call was a success.
3804 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3805 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3806 */
3807 TSS2_RC
3808 ifapi_json_TPM2B_PUBLIC_deserialize(json_object *jso, TPM2B_PUBLIC *out)
3809 {
3810 json_object *jso2;
3811 TSS2_RC res;
3812 LOG_TRACE("call");
3813 if (!ifapi_get_sub_object(jso, "size", &jso2)) {
3814 LOG_ERROR("Bad value");
3815 return TSS2_FAPI_RC_BAD_VALUE;
3816 }
3817 res = ifapi_json_UINT16_deserialize(jso2, &out->size);
3818 return_if_error(res, "BAD VALUE");
3819 if (!ifapi_get_sub_object(jso, "publicArea", &jso2)) {
3820 LOG_ERROR("Bad value");
3821 return TSS2_FAPI_RC_BAD_VALUE;
3822 }
3823 res = ifapi_json_TPMT_PUBLIC_deserialize(jso2, &out->publicArea);
3824 return_if_error(res, "BAD VALUE");
3825 return TSS2_RC_SUCCESS;
3826 }
3827
3828 /** Deserialize a TPM2B_PRIVATE json object.
3829 *
3830 * @param[in] jso the json object to be deserialized.
3831 * @param[out] out the deserialzed binary object.
3832 * @retval TSS2_RC_SUCCESS if the function call was a success.
3833 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3834 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3835 */
3836 TSS2_RC
3837 ifapi_json_TPM2B_PRIVATE_deserialize(json_object *jso, TPM2B_PRIVATE *out)
3838 {
3839 TSS2_RC r;
3840 LOG_TRACE("call");
3841 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3842
3843 UINT16 size = 0;
3844 r = ifapi_json_byte_deserialize(jso, sizeof(_PRIVATE), (BYTE *)&out->buffer,
3845 &size);
3846 return_if_error(r, "byte serialize");
3847
3848 out->size = size;
3849 return r;
3850 LOG_TRACE("true");
3851 return TSS2_RC_SUCCESS;
3852 }
3853
3854 /** Deserialize a TPM2_NT json object.
3855 *
3856 * @param[in] jso the json object to be deserialized.
3857 * @param[out] out the deserialzed binary object.
3858 * @retval TSS2_RC_SUCCESS if the function call was a success.
3859 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3860 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3861 */
3862 TSS2_RC
3863 ifapi_json_TPM2_NT_deserialize(json_object *jso, TPM2_NT *out)
3864 {
3865 static const struct { TPM2_NT in; const char *name; } tab[] = {
3866 { TPM2_NT_ORDINARY, "ORDINARY" },
3867 { TPM2_NT_COUNTER, "COUNTER" },
3868 { TPM2_NT_BITS, "BITS" },
3869 { TPM2_NT_EXTEND, "EXTEND" },
3870 { TPM2_NT_PIN_FAIL, "PIN_FAIL" },
3871 { TPM2_NT_PIN_PASS, "PIN_PASS" },
3872 };
3873
3874 const char *s = json_object_get_string(jso);
3875 const char *str = strip_prefix(s, "TPM_", "TPM2_", "NT_", NULL);
3876 LOG_TRACE("called for %s parsing %s", s, str);
3877
3878 if (str) {
3879 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
3880 if (strcasecmp(str, &tab[i].name[0]) == 0) {
3881 *out = tab[i].in;
3882 return TSS2_RC_SUCCESS;
3883 }
3884 }
3885 }
3886
3887 return ifapi_json_UINT8_deserialize(jso, out);
3888 }
3889
3890 /** Deserialize a TPMA_NV json object.
3891 *
3892 * @param[in] jso the json object to be deserialized.
3893 * @param[out] out the deserialzed binary object.
3894 * @retval TSS2_RC_SUCCESS if the function call was a success.
3895 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
3896 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3897 */
3898 TSS2_RC
3899 ifapi_json_TPMA_NV_deserialize(json_object *jso, TPMA_NV *out)
3900 {
3901 struct { TPMA_NV in; char *name; } tab[] = {
3902 { TPMA_NV_PPWRITE, "PPWRITE" },
3903 { TPMA_NV_OWNERWRITE, "OWNERWRITE" },
3904 { TPMA_NV_AUTHWRITE, "AUTHWRITE" },
3905 { TPMA_NV_POLICYWRITE, "POLICYWRITE" },
3906 { TPMA_NV_POLICY_DELETE, "POLICY_DELETE" },
3907 { TPMA_NV_WRITELOCKED, "WRITELOCKED" },
3908 { TPMA_NV_WRITEALL, "WRITEALL" },
3909 { TPMA_NV_WRITEDEFINE, "WRITEDEFINE" },
3910 { TPMA_NV_WRITE_STCLEAR, "WRITE_STCLEAR" },
3911 { TPMA_NV_GLOBALLOCK, "GLOBALLOCK" },
3912 { TPMA_NV_PPREAD, "PPREAD" },
3913 { TPMA_NV_OWNERREAD, "OWNERREAD" },
3914 { TPMA_NV_AUTHREAD, "AUTHREAD" },
3915 { TPMA_NV_POLICYREAD, "POLICYREAD" },
3916 { TPMA_NV_NO_DA, "NO_DA" },
3917 { TPMA_NV_ORDERLY, "ORDERLY" },
3918 { TPMA_NV_CLEAR_STCLEAR, "CLEAR_STCLEAR" },
3919 { TPMA_NV_READLOCKED, "READLOCKED" },
3920 { TPMA_NV_WRITTEN, "WRITTEN" },
3921 { TPMA_NV_PLATFORMCREATE, "PLATFORMCREATE" },
3922 { TPMA_NV_READ_STCLEAR, "READ_STCLEAR" },
3923 { TPM2_NT_ORDINARY << 4, "ORDINARY" },
3924 { TPM2_NT_COUNTER << 4, "COUNTER" },
3925 { TPM2_NT_BITS << 4, "BITS" },
3926 { TPM2_NT_EXTEND << 4, "EXTEND" },
3927 { TPM2_NT_PIN_FAIL << 4, "PIN_FAIL" },
3928 { TPM2_NT_PIN_PASS << 4, "PIN_PASS" },
3929 };
3930 size_t n = sizeof(tab) / sizeof(tab[0]);
3931 size_t i, j;
3932
3933 TPMI_YES_NO flag;
3934 TSS2_RC r;
3935
3936 LOG_TRACE("call");
3937 memset(out, 0, sizeof(TPMA_NV));
3938 json_type jso_type = json_object_get_type(jso);
3939 if (jso_type == json_type_array) {
3940 /* Cast (size_t) is necessary to support older version of libjson-c */
3941 for (i = 0; i < (size_t)json_object_array_length(jso); i++) {
3942 json_object *jso2 = json_object_array_get_idx(jso, i);
3943 if (json_object_get_type(jso2) == json_type_object) {
3944 if (!json_object_object_get_ex(jso2, "TPM2_NT", &jso2)) {
3945 LOG_ERROR("Found object in array without TPM2_NT");
3946 return TSS2_FAPI_RC_BAD_VALUE;
3947 }
3948 TPM2_NT out2;
3949 TSS2_RC r = ifapi_json_TPM2_NT_deserialize(jso2, &out2);
3950 return_if_error(r, "Bad value");
3951 *out |= out2 << 4;
3952 continue;
3953 }
3954 const char *token = strip_prefix(json_object_get_string(jso2),
3955 "TPM_", "TPM2_", "TPMA_", "NV_",
3956 "TPM2_", "NT_", NULL);
3957 if (!token) {
3958 LOG_ERROR("Bad object; expected array of strings.");
3959 return TSS2_FAPI_RC_BAD_VALUE;
3960 }
3961 for (j = 0; j < n; j++) {
3962 if (strcasecmp(tab[j].name, token) == 0) {
3963 *out |= tab[j].in;
3964 break;
3965 }
3966 }
3967 if (j == n) {
3968 LOG_ERROR("Unknown value: %s", json_object_get_string(jso2));
3969 return TSS2_FAPI_RC_BAD_VALUE;
3970 }
3971 }
3972 } else if (jso_type == json_type_object) {
3973 json_object_object_foreach(jso, key, val) {
3974 const char *token = strip_prefix(key, "TPM_", "TPM2_", "TPMA_", "NV_", "TPM2_", NULL);
3975 if (strcasecmp(token, "NT") == 0) {
3976 TPM2_NT out2;
3977 TSS2_RC r = ifapi_json_TPM2_NT_deserialize(val, &out2);
3978 return_if_error(r, "Bad value");
3979 *out |= out2 << 4;
3980 continue;
3981 }
3982 token = strip_prefix(token, "NT_", NULL);
3983 r = get_boolean_from_json(val, &flag);
3984 return_if_error2(r, "Boolean value expected at key: %s", key);
3985 for (j = 0; j < n; j++) {
3986 if (strcasecmp(tab[j].name, token) == 0) {
3987 if (flag)
3988 *out |= tab[j].in;
3989 break;
3990 }
3991 }
3992 if (j == n) {
3993 LOG_ERROR("Unknown key: %s", key);
3994 return TSS2_FAPI_RC_BAD_VALUE;
3995 }
3996 }
3997 } else {
3998 const char *token;
3999 token = json_object_get_string(jso);
4000 int64_t i64;
4001 if (!get_number(token, &i64)) {
4002 LOG_ERROR("Bad value");
4003 return TSS2_FAPI_RC_BAD_VALUE;
4004 }
4005 *out = (TPMA_NV) i64;
4006 if ((int64_t)*out != i64) {
4007 LOG_ERROR("Bad value");
4008 return TSS2_FAPI_RC_BAD_VALUE;
4009 }
4010 return TSS2_RC_SUCCESS;
4011 }
4012 LOG_TRACE("true");
4013 return TSS2_RC_SUCCESS;
4014 }
4015
4016 /** Deserialize a TPMS_NV_PUBLIC json object.
4017 *
4018 * @param[in] jso the json object to be deserialized.
4019 * @param[out] out the deserialzed binary object.
4020 * @retval TSS2_RC_SUCCESS if the function call was a success.
4021 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
4022 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
4023 */
4024 TSS2_RC
4025 ifapi_json_TPMS_NV_PUBLIC_deserialize(json_object *jso, TPMS_NV_PUBLIC *out)
4026 {
4027 json_object *jso2;
4028 TSS2_RC r;
4029 LOG_TRACE("call");
4030 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
4031
4032 if (!ifapi_get_sub_object(jso, "nvIndex", &jso2)) {
4033 LOG_ERROR("Bad value");
4034 return TSS2_FAPI_RC_BAD_VALUE;
4035 }
4036 r = ifapi_json_TPMI_RH_NV_INDEX_deserialize(jso2, &out->nvIndex);
4037 return_if_error(r, "BAD VALUE");
4038
4039 if (!ifapi_get_sub_object(jso, "nameAlg", &jso2)) {
4040 LOG_ERROR("Bad value");
4041 return TSS2_FAPI_RC_BAD_VALUE;
4042 }
4043 r = ifapi_json_TPMI_ALG_HASH_deserialize(jso2, &out->nameAlg);
4044 return_if_error(r, "BAD VALUE");
4045
4046 if (!ifapi_get_sub_object(jso, "attributes", &jso2)) {
4047 LOG_ERROR("Bad value");
4048 return TSS2_FAPI_RC_BAD_VALUE;
4049 }
4050 r = ifapi_json_TPMA_NV_deserialize(jso2, &out->attributes);
4051 return_if_error(r, "BAD VALUE");
4052
4053 if (!ifapi_get_sub_object(jso, "authPolicy", &jso2)) {
4054 LOG_ERROR("Bad value");
4055 return TSS2_FAPI_RC_BAD_VALUE;
4056 }
4057 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->authPolicy);
4058 return_if_error(r, "BAD VALUE");
4059
4060 if (!ifapi_get_sub_object(jso, "dataSize", &jso2)) {
4061 LOG_ERROR("Bad value");
4062 return TSS2_FAPI_RC_BAD_VALUE;
4063 }
4064 r = ifapi_json_UINT16_deserialize(jso2, &out->dataSize);
4065 return_if_error(r, "BAD VALUE");
4066
4067 LOG_TRACE("true");
4068 return TSS2_RC_SUCCESS;
4069 }
4070
4071 /** Deserialize a TPM2B_NV_PUBLIC json object.
4072 * @param[in] jso the json object to be deserialized.
4073 * @param[out] out the deserialzed binary object.
4074 * @retval TSS2_RC_SUCCESS if the function call was a success.
4075 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
4076 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
4077 */
4078 TSS2_RC
4079 ifapi_json_TPM2B_NV_PUBLIC_deserialize(json_object *jso, TPM2B_NV_PUBLIC *out)
4080 {
4081 json_object *jso2;
4082 TSS2_RC res;
4083 LOG_TRACE("call");
4084 if (!ifapi_get_sub_object(jso, "size", &jso2)) {
4085 LOG_ERROR("Bad value");
4086 return TSS2_FAPI_RC_BAD_VALUE;
4087 }
4088 res = ifapi_json_UINT16_deserialize(jso2, &out->size);
4089 return_if_error(res, "BAD VALUE");
4090 if (!ifapi_get_sub_object(jso, "nvPublic", &jso2)) {
4091 LOG_ERROR("Bad value");
4092 return TSS2_FAPI_RC_BAD_VALUE;
4093 }
4094 res = ifapi_json_TPMS_NV_PUBLIC_deserialize(jso2, &out->nvPublic);
4095 return_if_error(res, "BAD VALUE");
4096 return TSS2_RC_SUCCESS;
4097 }
4098
4099 /** Deserialize a TPMS_CREATION_DATA json object.
4100 *
4101 * @param[in] jso the json object to be deserialized.
4102 * @param[out] out the deserialzed binary object.
4103 * @retval TSS2_RC_SUCCESS if the function call was a success.
4104 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
4105 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
4106 */
4107 TSS2_RC
4108 ifapi_json_TPMS_CREATION_DATA_deserialize(json_object *jso,
4109 TPMS_CREATION_DATA *out)
4110 {
4111 json_object *jso2;
4112 TSS2_RC r;
4113 LOG_TRACE("call");
4114 return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
4115
4116 if (!ifapi_get_sub_object(jso, "pcrSelect", &jso2)) {
4117 LOG_ERROR("Bad value");
4118 return TSS2_FAPI_RC_BAD_VALUE;
4119 }
4120 r = ifapi_json_TPML_PCR_SELECTION_deserialize(jso2, &out->pcrSelect);
4121 return_if_error(r, "BAD VALUE");
4122
4123 if (!ifapi_get_sub_object(jso, "pcrDigest", &jso2)) {
4124 LOG_ERROR("Bad value");
4125 return TSS2_FAPI_RC_BAD_VALUE;
4126 }
4127 r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->pcrDigest);
4128 return_if_error(r, "BAD VALUE");
4129
4130 if (!ifapi_get_sub_object(jso, "locality", &jso2)) {
4131 LOG_ERROR("Bad value");
4132 return TSS2_FAPI_RC_BAD_VALUE;
4133 }
4134 r = ifapi_json_TPMA_LOCALITY_deserialize(jso2, &out->locality);
4135 return_if_error(r, "BAD VALUE");
4136
4137 if (!ifapi_get_sub_object(jso, "parentNameAlg", &jso2)) {
4138 LOG_ERROR("Bad value");
4139 return TSS2_FAPI_RC_BAD_VALUE;
4140 }
4141 r = ifapi_json_TPM2_ALG_ID_deserialize(jso2, &out->parentNameAlg);
4142 return_if_error(r, "BAD VALUE");
4143
4144 if (!ifapi_get_sub_object(jso, "parentName", &jso2)) {
4145 LOG_ERROR("Bad value");
4146 return TSS2_FAPI_RC_BAD_VALUE;
4147 }
4148 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->parentName);
4149 return_if_error(r, "BAD VALUE");
4150
4151 if (!ifapi_get_sub_object(jso, "parentQualifiedName", &jso2)) {
4152 LOG_ERROR("Bad value");
4153 return TSS2_FAPI_RC_BAD_VALUE;
4154 }
4155 r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->parentQualifiedName);
4156 return_if_error(r, "BAD VALUE");
4157
4158 if (!ifapi_get_sub_object(jso, "outsideInfo", &jso2)) {
4159 LOG_ERROR("Bad value");
4160 return TSS2_FAPI_RC_BAD_VALUE;
4161 }
4162 r = ifapi_json_TPM2B_DATA_deserialize(jso2, &out->outsideInfo);
4163 return_if_error(r, "BAD VALUE");
4164 LOG_TRACE("true");
4165 return TSS2_RC_SUCCESS;
4166 }
4167
4168 /** Deserialize a TPM2B_CREATION_DATA json object.
4169 * @param[in] jso the json object to be deserialized.
4170 * @param[out] out the deserialzed binary object.
4171 * @retval TSS2_RC_SUCCESS if the function call was a success.
4172 * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
4173 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
4174 */
4175 TSS2_RC
4176 ifapi_json_TPM2B_CREATION_DATA_deserialize(json_object *jso,
4177 TPM2B_CREATION_DATA *out)
4178 {
4179 json_object *jso2;
4180 TSS2_RC res;
4181 LOG_TRACE("call");
4182 if (!ifapi_get_sub_object(jso, "size", &jso2)) {
4183 LOG_ERROR("Bad value");
4184 return TSS2_FAPI_RC_BAD_VALUE;
4185 }
4186 res = ifapi_json_UINT16_deserialize(jso2, &out->size);
4187 return_if_error(res, "BAD VALUE");
4188 if (!ifapi_get_sub_object(jso, "creationData", &jso2)) {
4189 LOG_ERROR("Bad value");
4190 return TSS2_FAPI_RC_BAD_VALUE;
4191 }
4192 res = ifapi_json_TPMS_CREATION_DATA_deserialize(jso2, &out->creationData);
4193 return_if_error(res, "BAD VALUE");
4194 return TSS2_RC_SUCCESS;
4195 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef FAPI_TPM_JSON_DESERIALIZE_H
6 #define FAPI_TPM_JSON_DESERIALIZE_H
7
8 #include <stdbool.h>
9 #include <json-c/json.h>
10 #include <json-c/json_util.h>
11
12 #include "tss2_tpm2_types.h"
13 #include "fapi_int.h"
14 #define YES 1
15 #define NO 0
16
17 TSS2_RC
18 ifapi_json_BYTE_array_deserialize(size_t max, json_object *jso, BYTE *out);
19
20 TSS2_RC
21 ifapi_json_UINT8_ARY_deserialize(json_object *jso, UINT8_ARY *out);
22
23 bool
24 ifapi_get_sub_object(json_object *jso, char *name, json_object **sub_jso);
25
26 TSS2_RC
27 ifapi_json_BYTE_deserialize(json_object *jso, BYTE *out);
28
29 TSS2_RC
30 ifapi_json_UINT16_deserialize(json_object *jso, UINT16 *out);
31
32 TSS2_RC
33 ifapi_json_UINT32_deserialize(json_object *jso, UINT32 *out);
34
35 TSS2_RC
36 ifapi_json_UINT64_deserialize(json_object *jso, UINT64 *out);
37
38 TSS2_RC
39 ifapi_json_TPM2_GENERATED_deserialize(json_object *jso, TPM2_GENERATED *out);
40
41 TSS2_RC
42 ifapi_json_TPM2_ALG_ID_deserialize(json_object *jso, TPM2_ALG_ID *out);
43
44 TSS2_RC
45 ifapi_json_TPM2_ECC_CURVE_deserialize(json_object *jso, TPM2_ECC_CURVE *out);
46
47 TSS2_RC
48 ifapi_json_TPM2_CC_deserialize(json_object *jso, TPM2_CC *out);
49
50 TSS2_RC
51 ifapi_json_TPM2_EO_deserialize(json_object *jso, TPM2_EO *out);
52
53 TSS2_RC
54 ifapi_json_TPM2_ST_deserialize(json_object *jso, TPM2_ST *out);
55
56 TSS2_RC
57 ifapi_json_TPM2_PT_PCR_deserialize(json_object *jso, TPM2_PT_PCR *out);
58
59 TSS2_RC
60 ifapi_json_TPM2_HANDLE_deserialize(json_object *jso, TPM2_HANDLE *out);
61
62 TSS2_RC
63 ifapi_json_TPMA_OBJECT_deserialize(json_object *jso, TPMA_OBJECT *out);
64
65 TSS2_RC
66 ifapi_json_TPMA_LOCALITY_deserialize(json_object *jso, TPMA_LOCALITY *out);
67
68 TSS2_RC
69 ifapi_json_TPMI_YES_NO_deserialize(json_object *jso, TPMI_YES_NO *out);
70
71 TSS2_RC
72 ifapi_json_TPMI_RH_HIERARCHY_deserialize(json_object *jso,
73 TPMI_RH_HIERARCHY *out);
74
75 TSS2_RC
76 ifapi_json_TPMI_RH_NV_INDEX_deserialize(json_object *jso,
77 TPMI_RH_NV_INDEX *out);
78
79 TSS2_RC
80 ifapi_json_TPMI_ALG_HASH_deserialize(json_object *jso, TPMI_ALG_HASH *out);
81
82 TSS2_RC
83 ifapi_json_TPMI_ALG_SYM_deserialize(json_object *jso, TPMI_ALG_SYM *out);
84
85 TSS2_RC
86 ifapi_json_TPMI_ALG_SYM_OBJECT_deserialize(json_object *jso,
87 TPMI_ALG_SYM_OBJECT *out);
88
89 TSS2_RC
90 ifapi_json_TPMI_ALG_SYM_MODE_deserialize(json_object *jso,
91 TPMI_ALG_SYM_MODE *out);
92
93 TSS2_RC
94 ifapi_json_TPMI_ALG_KDF_deserialize(json_object *jso, TPMI_ALG_KDF *out);
95
96 TSS2_RC
97 ifapi_json_TPMI_ALG_SIG_SCHEME_deserialize(json_object *jso,
98 TPMI_ALG_SIG_SCHEME *out);
99
100 TSS2_RC
101 ifapi_json_TPMS_EMPTY_deserialize(json_object *jso, TPMS_EMPTY *out);
102
103 TSS2_RC
104 ifapi_json_TPMU_HA_deserialize(UINT32 selector, json_object *jso, TPMU_HA *out);
105
106 TSS2_RC
107 ifapi_json_TPMT_HA_deserialize(json_object *jso, TPMT_HA *out);
108
109 TSS2_RC
110 ifapi_json_TPM2B_DIGEST_deserialize(json_object *jso, TPM2B_DIGEST *out);
111
112 TSS2_RC
113 ifapi_json_TPM2B_DATA_deserialize(json_object *jso, TPM2B_DATA *out);
114
115 TSS2_RC
116 ifapi_json_TPM2B_NONCE_deserialize(json_object *jso, TPM2B_NONCE *out);
117
118 TSS2_RC
119 ifapi_json_TPM2B_OPERAND_deserialize(json_object *jso, TPM2B_OPERAND *out);
120
121 TSS2_RC
122 ifapi_json_TPM2B_EVENT_deserialize(json_object *jso, TPM2B_EVENT *out);
123
124 TSS2_RC
125 ifapi_json_TPM2B_MAX_NV_BUFFER_deserialize(json_object *jso,
126 TPM2B_MAX_NV_BUFFER *out);
127
128 TSS2_RC
129 ifapi_json_TPM2B_NAME_deserialize(json_object *jso, TPM2B_NAME *out);
130
131 TSS2_RC
132 ifapi_json_TPMS_PCR_SELECT_deserialize(json_object *jso, TPMS_PCR_SELECT *out);
133
134 TSS2_RC
135 ifapi_json_TPMS_PCR_SELECTION_deserialize(json_object *jso,
136 TPMS_PCR_SELECTION *out);
137
138 TSS2_RC
139 ifapi_json_TPMT_TK_CREATION_deserialize(json_object *jso,
140 TPMT_TK_CREATION *out);
141
142 TSS2_RC
143 ifapi_json_TPMT_TK_VERIFIED_deserialize(json_object *jso,
144 TPMT_TK_VERIFIED *out);
145
146 TSS2_RC
147 ifapi_json_TPML_DIGEST_VALUES_deserialize(json_object *jso,
148 TPML_DIGEST_VALUES *out);
149
150 TSS2_RC
151 ifapi_json_TPML_PCR_SELECTION_deserialize(json_object *jso,
152 TPML_PCR_SELECTION *out);
153
154 TSS2_RC
155 ifapi_json_TPMS_CLOCK_INFO_deserialize(json_object *jso, TPMS_CLOCK_INFO *out);
156
157 TSS2_RC
158 ifapi_json_TPMS_TIME_INFO_deserialize(json_object *jso, TPMS_TIME_INFO *out);
159
160 TSS2_RC
161 ifapi_json_TPMS_TIME_ATTEST_INFO_deserialize(json_object *jso,
162 TPMS_TIME_ATTEST_INFO *out);
163
164 TSS2_RC
165 ifapi_json_TPMS_CERTIFY_INFO_deserialize(json_object *jso,
166 TPMS_CERTIFY_INFO *out);
167
168 TSS2_RC
169 ifapi_json_TPMS_QUOTE_INFO_deserialize(json_object *jso, TPMS_QUOTE_INFO *out);
170
171 TSS2_RC
172 ifapi_json_TPMS_COMMAND_AUDIT_INFO_deserialize(json_object *jso,
173 TPMS_COMMAND_AUDIT_INFO *out);
174
175 TSS2_RC
176 ifapi_json_TPMS_SESSION_AUDIT_INFO_deserialize(json_object *jso,
177 TPMS_SESSION_AUDIT_INFO *out);
178
179 TSS2_RC
180 ifapi_json_TPMS_CREATION_INFO_deserialize(json_object *jso,
181 TPMS_CREATION_INFO *out);
182
183 TSS2_RC
184 ifapi_json_TPMS_NV_CERTIFY_INFO_deserialize(json_object *jso,
185 TPMS_NV_CERTIFY_INFO *out);
186
187 TSS2_RC
188 ifapi_json_TPMI_ST_ATTEST_deserialize(json_object *jso, TPMI_ST_ATTEST *out);
189
190 TSS2_RC
191 ifapi_json_TPMU_ATTEST_deserialize(UINT32 selector, json_object *jso,
192 TPMU_ATTEST *out);
193
194 TSS2_RC
195 ifapi_json_TPMS_ATTEST_deserialize(json_object *jso, TPMS_ATTEST *out);
196
197 TSS2_RC
198 ifapi_json_TPMI_AES_KEY_BITS_deserialize(json_object *jso,
199 TPMI_AES_KEY_BITS *out);
200
201 TSS2_RC
202 ifapi_json_TPMU_SYM_KEY_BITS_deserialize(UINT32 selector, json_object *jso,
203 TPMU_SYM_KEY_BITS *out);
204
205 TSS2_RC
206 ifapi_json_TPMU_SYM_MODE_deserialize(UINT32 selector, json_object *jso,
207 TPMU_SYM_MODE *out);
208
209 TSS2_RC
210 ifapi_json_TPMT_SYM_DEF_deserialize(json_object *jso, TPMT_SYM_DEF *out);
211
212 TSS2_RC
213 ifapi_json_TPMT_SYM_DEF_OBJECT_deserialize(json_object *jso,
214 TPMT_SYM_DEF_OBJECT *out);
215
216 TSS2_RC
217 ifapi_json_TPMS_SYMCIPHER_PARMS_deserialize(json_object *jso,
218 TPMS_SYMCIPHER_PARMS *out);
219
220 TSS2_RC
221 ifapi_json_TPMS_SCHEME_HASH_deserialize(json_object *jso,
222 TPMS_SCHEME_HASH *out);
223
224 TSS2_RC
225 ifapi_json_TPMS_SCHEME_ECDAA_deserialize(json_object *jso,
226 TPMS_SCHEME_ECDAA *out);
227
228 TSS2_RC
229 ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_deserialize(json_object *jso,
230 TPMI_ALG_KEYEDHASH_SCHEME *out);
231
232 TSS2_RC
233 ifapi_json_TPMS_SCHEME_HMAC_deserialize(json_object *jso,
234 TPMS_SCHEME_HMAC *out);
235
236 TSS2_RC
237 ifapi_json_TPMS_SCHEME_XOR_deserialize(json_object *jso, TPMS_SCHEME_XOR *out);
238
239 TSS2_RC
240 ifapi_json_TPMU_SCHEME_KEYEDHASH_deserialize(UINT32 selector, json_object *jso,
241 TPMU_SCHEME_KEYEDHASH *out);
242
243 TSS2_RC
244 ifapi_json_TPMT_KEYEDHASH_SCHEME_deserialize(json_object *jso,
245 TPMT_KEYEDHASH_SCHEME *out);
246
247 TSS2_RC
248 ifapi_json_TPMS_SIG_SCHEME_RSASSA_deserialize(json_object *jso,
249 TPMS_SIG_SCHEME_RSASSA *out);
250
251 TSS2_RC
252 ifapi_json_TPMS_SIG_SCHEME_RSAPSS_deserialize(json_object *jso,
253 TPMS_SIG_SCHEME_RSAPSS *out);
254
255 TSS2_RC
256 ifapi_json_TPMS_SIG_SCHEME_ECDSA_deserialize(json_object *jso,
257 TPMS_SIG_SCHEME_ECDSA *out);
258
259 TSS2_RC
260 ifapi_json_TPMS_SIG_SCHEME_SM2_deserialize(json_object *jso,
261 TPMS_SIG_SCHEME_SM2 *out);
262
263 TSS2_RC
264 ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_deserialize(json_object *jso,
265 TPMS_SIG_SCHEME_ECSCHNORR *out);
266
267 TSS2_RC
268 ifapi_json_TPMS_SIG_SCHEME_ECDAA_deserialize(json_object *jso,
269 TPMS_SIG_SCHEME_ECDAA *out);
270
271 TSS2_RC
272 ifapi_json_TPMU_SIG_SCHEME_deserialize(UINT32 selector, json_object *jso,
273 TPMU_SIG_SCHEME *out);
274
275 TSS2_RC
276 ifapi_json_TPMT_SIG_SCHEME_deserialize(json_object *jso, TPMT_SIG_SCHEME *out);
277
278 TSS2_RC
279 ifapi_json_TPMS_ENC_SCHEME_OAEP_deserialize(json_object *jso,
280 TPMS_ENC_SCHEME_OAEP *out);
281
282 TSS2_RC
283 ifapi_json_TPMS_ENC_SCHEME_RSAES_deserialize(json_object *jso,
284 TPMS_ENC_SCHEME_RSAES *out);
285
286 TSS2_RC
287 ifapi_json_TPMS_KEY_SCHEME_ECDH_deserialize(json_object *jso,
288 TPMS_KEY_SCHEME_ECDH *out);
289
290 TSS2_RC
291 ifapi_json_TPMS_SCHEME_MGF1_deserialize(json_object *jso,
292 TPMS_SCHEME_MGF1 *out);
293
294 TSS2_RC
295 ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_deserialize(json_object *jso,
296 TPMS_SCHEME_KDF1_SP800_56A *out);
297
298 TSS2_RC
299 ifapi_json_TPMS_SCHEME_KDF1_SP800_108_deserialize(json_object *jso,
300 TPMS_SCHEME_KDF1_SP800_108 *out);
301
302 TSS2_RC
303 ifapi_json_TPMU_KDF_SCHEME_deserialize(UINT32 selector, json_object *jso,
304 TPMU_KDF_SCHEME *out);
305
306 TSS2_RC
307 ifapi_json_TPMT_KDF_SCHEME_deserialize(json_object *jso, TPMT_KDF_SCHEME *out);
308
309 TSS2_RC
310 ifapi_json_TPMU_ASYM_SCHEME_deserialize(UINT32 selector, json_object *jso,
311 TPMU_ASYM_SCHEME *out);
312
313 TSS2_RC
314 ifapi_json_TPMI_ALG_RSA_SCHEME_deserialize(json_object *jso,
315 TPMI_ALG_RSA_SCHEME *out);
316
317 TSS2_RC
318 ifapi_json_TPMT_RSA_SCHEME_deserialize(json_object *jso, TPMT_RSA_SCHEME *out);
319
320 TSS2_RC
321 ifapi_json_TPMI_ALG_RSA_DECRYPT_deserialize(json_object *jso,
322 TPMI_ALG_RSA_DECRYPT *out);
323
324 TSS2_RC
325 ifapi_json_TPMT_RSA_DECRYPT_deserialize(json_object *jso,
326 TPMT_RSA_DECRYPT *out);
327
328 TSS2_RC
329 ifapi_json_TPM2B_PUBLIC_KEY_RSA_deserialize(json_object *jso,
330 TPM2B_PUBLIC_KEY_RSA *out);
331
332 TSS2_RC
333 ifapi_json_TPMI_RSA_KEY_BITS_deserialize(json_object *jso,
334 TPMI_RSA_KEY_BITS *out);
335
336 TSS2_RC
337 ifapi_json_TPM2B_ECC_PARAMETER_deserialize(json_object *jso,
338 TPM2B_ECC_PARAMETER *out);
339
340 TSS2_RC
341 ifapi_json_TPMS_ECC_POINT_deserialize(json_object *jso, TPMS_ECC_POINT *out);
342
343 TSS2_RC
344 ifapi_json_TPMI_ALG_ECC_SCHEME_deserialize(json_object *jso,
345 TPMI_ALG_ECC_SCHEME *out);
346
347 TSS2_RC
348 ifapi_json_TPMI_ECC_CURVE_deserialize(json_object *jso, TPMI_ECC_CURVE *out);
349
350 TSS2_RC
351 ifapi_json_TPMT_ECC_SCHEME_deserialize(json_object *jso, TPMT_ECC_SCHEME *out);
352
353 TSS2_RC
354 ifapi_json_TPMS_SIGNATURE_RSA_deserialize(json_object *jso,
355 TPMS_SIGNATURE_RSA *out);
356
357 TSS2_RC
358 ifapi_json_TPMS_SIGNATURE_RSASSA_deserialize(json_object *jso,
359 TPMS_SIGNATURE_RSASSA *out);
360
361 TSS2_RC
362 ifapi_json_TPMS_SIGNATURE_RSAPSS_deserialize(json_object *jso,
363 TPMS_SIGNATURE_RSAPSS *out);
364
365 TSS2_RC
366 ifapi_json_TPMS_SIGNATURE_ECC_deserialize(json_object *jso,
367 TPMS_SIGNATURE_ECC *out);
368
369 TSS2_RC
370 ifapi_json_TPMS_SIGNATURE_ECDSA_deserialize(json_object *jso,
371 TPMS_SIGNATURE_ECDSA *out);
372
373 TSS2_RC
374 ifapi_json_TPMS_SIGNATURE_ECDAA_deserialize(json_object *jso,
375 TPMS_SIGNATURE_ECDAA *out);
376
377 TSS2_RC
378 ifapi_json_TPMS_SIGNATURE_SM2_deserialize(json_object *jso,
379 TPMS_SIGNATURE_SM2 *out);
380
381 TSS2_RC
382 ifapi_json_TPMS_SIGNATURE_ECSCHNORR_deserialize(json_object *jso,
383 TPMS_SIGNATURE_ECSCHNORR *out);
384
385 TSS2_RC
386 ifapi_json_TPMU_SIGNATURE_deserialize(UINT32 selector, json_object *jso,
387 TPMU_SIGNATURE *out);
388
389 TSS2_RC
390 ifapi_json_TPMT_SIGNATURE_deserialize(json_object *jso, TPMT_SIGNATURE *out);
391
392 TSS2_RC
393 ifapi_json_TPM2B_ENCRYPTED_SECRET_deserialize(json_object *jso,
394 TPM2B_ENCRYPTED_SECRET *out);
395
396 TSS2_RC
397 ifapi_json_TPMI_ALG_PUBLIC_deserialize(json_object *jso, TPMI_ALG_PUBLIC *out);
398
399 TSS2_RC
400 ifapi_json_TPMU_PUBLIC_ID_deserialize(UINT32 selector, json_object *jso,
401 TPMU_PUBLIC_ID *out);
402
403 TSS2_RC
404 ifapi_json_TPMS_KEYEDHASH_PARMS_deserialize(json_object *jso,
405 TPMS_KEYEDHASH_PARMS *out);
406
407 TSS2_RC
408 ifapi_json_TPMS_RSA_PARMS_deserialize(json_object *jso, TPMS_RSA_PARMS *out);
409
410 TSS2_RC
411 ifapi_json_TPMS_ECC_PARMS_deserialize(json_object *jso, TPMS_ECC_PARMS *out);
412
413 TSS2_RC
414 ifapi_json_TPMU_PUBLIC_PARMS_deserialize(UINT32 selector, json_object *jso,
415 TPMU_PUBLIC_PARMS *out);
416
417 TSS2_RC
418 ifapi_json_TPMT_PUBLIC_deserialize(json_object *jso, TPMT_PUBLIC *out);
419
420 TSS2_RC
421 ifapi_json_TPM2B_PUBLIC_deserialize(json_object *jso, TPM2B_PUBLIC *out);
422
423 TSS2_RC
424 ifapi_json_TPM2B_PRIVATE_deserialize(json_object *jso, TPM2B_PRIVATE *out);
425
426 TSS2_RC
427 ifapi_json_TPM2_NT_deserialize(json_object *jso, TPM2_NT *out);
428
429 TSS2_RC
430 ifapi_json_TPMA_NV_deserialize(json_object *jso, TPMA_NV *out);
431
432 TSS2_RC
433 ifapi_json_TPMS_NV_PUBLIC_deserialize(json_object *jso, TPMS_NV_PUBLIC *out);
434
435 TSS2_RC
436 ifapi_json_TPM2B_NV_PUBLIC_deserialize(json_object *jso, TPM2B_NV_PUBLIC *out);
437
438 TSS2_RC
439 ifapi_json_TPMS_CREATION_DATA_deserialize(json_object *jso,
440 TPMS_CREATION_DATA *out);
441
442 TSS2_RC
443 ifapi_json_TPM2B_CREATION_DATA_deserialize(json_object *jso,
444 TPM2B_CREATION_DATA *out);
445
446 #endif /* FAPI_TPM_JSON_DESERIALIZE_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11
12 #include "tpm_json_serialize.h"
13 #define LOGMODULE fapijson
14 #include "util/log.h"
15 #include "util/aux_util.h"
16
17 #define CHECK_IN_LIST(type, needle, ...) \
18 type tab[] = { __VA_ARGS__ }; \
19 size_t i; \
20 for(i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) \
21 if (needle == tab[i]) \
22 break; \
23 if (i == sizeof(tab) / sizeof(tab[0])) { \
24 LOG_ERROR("Bad value"); \
25 return TSS2_FAPI_RC_BAD_VALUE; \
26 }
27
28 /** Serialize a TPMS_EMPTY.
29 *
30 * @param[in] in not used.
31 * @param[in] jso not used.
32 * @retval TSS2_RC_SUCCESS is always returnde.
33 */
34 TSS2_RC
35 ifapi_json_TPMS_EMPTY_serialize(const TPMS_EMPTY *in, json_object **jso)
36 {
37 (void)(in);
38 (void)(jso);
39 return TSS2_RC_SUCCESS;
40 }
41
42 /** Serialize a pcr selection to json
43 *
44 * @param[in] sizeofSelect size of selection byte array.
45 * @param[in] pcrSelect selection array.
46 * @param[out] jso pointer to the json object.
47 * @retval TSS2_RC_SUCCESS if the function call was a success.
48 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
49 * @retval TSS2_FAPI_RC_BAD_VALUE if sizeofSelect is too big.
50 */
51 TSS2_RC
52 ifapi_json_pcr_select_serialize(
53 const UINT8 sizeofSelect,
54 const BYTE pcrSelect[],
55 json_object **jso)
56 {
57 if (*jso == NULL) {
58 *jso = json_object_new_array();
59 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
60 }
61 if (sizeofSelect > TPM2_PCR_SELECT_MAX) {
62 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_PCR_SELECT_MAX)",
63 (size_t)sizeofSelect, (size_t)TPM2_PCR_SELECT_MAX);
64 return TSS2_FAPI_RC_BAD_VALUE;
65 }
66 UINT32 i1, i2;
67 json_object *jso2;
68 for (i1 = 0; i1 < TPM2_PCR_LAST - TPM2_PCR_FIRST; i1++) {
69 i2 = i1 + TPM2_PCR_FIRST;
70 if (pcrSelect[i2 / 8] & (BYTE)(1 << (i2 % 8))) {
71 jso2 = json_object_new_int(i2);
72 return_if_null(jso2, "Out of memory.", TSS2_FAPI_RC_MEMORY);
73 json_object_array_add(*jso, jso2);
74 }
75 }
76 return TSS2_RC_SUCCESS;
77 }
78
79 /** Serialize a TPMS_PCR_SELECT structure to json.
80 *
81 * @param[in] in value to be serialized.
82 * @param[out] jso pointer to the json object.
83 * @retval TSS2_RC_SUCCESS if the function call was a success.
84 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
85 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_PCR_SELECTION.
86 */
87 TSS2_RC
88 ifapi_json_TPMS_PCR_SELECT_serialize(const TPMS_PCR_SELECT *in,
89 json_object **jso)
90 {
91 TSS2_RC r;
92
93 r = ifapi_json_pcr_select_serialize(in->sizeofSelect, &in->pcrSelect[0], jso);
94 return_if_error(r, "Serialize pcr selection");
95
96 return TSS2_RC_SUCCESS;
97 }
98
99
100 /** Serialize a TPMS_PCR_SELECTION structure to json.
101 *
102 * @param[in] in value to be serialized.
103 * @param[out] jso pointer to the json object.
104 * @retval TSS2_RC_SUCCESS if the function call was a success.
105 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
106 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_PCR_SELECTION.
107 */
108 TSS2_RC
109 ifapi_json_TPMS_PCR_SELECTION_serialize(const TPMS_PCR_SELECTION *in,
110 json_object **jso)
111 {
112 if (*jso == NULL) {
113 *jso = json_object_new_object();
114 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
115 }
116 TSS2_RC r;
117 json_object *jso2 = NULL;
118 r = ifapi_json_TPMI_ALG_HASH_serialize(in->hash, &jso2);
119 return_if_error(r, "Serialize pcr selection");
120
121 json_object_object_add(*jso, "hash", jso2);
122 jso2 = NULL;
123 r = ifapi_json_pcr_select_serialize(in->sizeofSelect, &in->pcrSelect[0], &jso2);
124 return_if_error(r, "Serialize pcr selection");
125
126 json_object_object_add(*jso, "pcrSelect", jso2);
127 return TSS2_RC_SUCCESS;
128 }
129
130 /** Serialize a TPMS_TAGGED_PCR_SELECT structure to json.
131 *
132 * @param[in] in value to be serialized.
133 * @param[out] jso pointer to the json object.
134 * @retval TSS2_RC_SUCCESS if the function call was a success.
135 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
136 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_TAGGED_PCR_SELECT.
137 */
138 TSS2_RC
139 ifapi_json_TPMS_TAGGED_PCR_SELECT_serialize(const TPMS_TAGGED_PCR_SELECT *in,
140 json_object **jso)
141 {
142 TSS2_RC r;
143 if (*jso == NULL)
144 *jso = json_object_new_object();
145 json_object *jso2 = NULL;
146 r = ifapi_json_TPM2_PT_PCR_serialize(in->tag, &jso2);
147 return_if_error(r, "Serialize pcr selection");
148
149 json_object_object_add(*jso, "tag", jso2);
150 jso2 = NULL;
151 r = ifapi_json_pcr_select_serialize(in->sizeofSelect, &in->pcrSelect[0], &jso2);
152 return_if_error(r, "Serialize pcr selection");
153
154 json_object_object_add(*jso, "pcrSelect", jso2);
155 return TSS2_RC_SUCCESS;
156 }
157
158 /** Serialize a base_type UINT16 to json.
159 *
160 * @param[in] in value to be serialized.
161 * @param[out] jso pointer to the json object.
162 * @retval TSS2_RC_SUCCESS if the function call was a success.
163 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
164 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type UINT16.
165 */
166 TSS2_RC
167 ifapi_json_UINT16_serialize(const UINT16 in, json_object **jso)
168 {
169 *jso = json_object_new_int64(in);
170 if (*jso == NULL) {
171 LOG_ERROR("Bad value %04"PRIx16"", in);
172 return TSS2_FAPI_RC_BAD_VALUE;
173 }
174 return TSS2_RC_SUCCESS;
175 }
176
177 /** Serialize a base_type UINT32 to json.
178 *
179 * @param[in] in value to be serialized.
180 * @param[out] jso pointer to the json object.
181 * @retval TSS2_RC_SUCCESS if the function call was a success.
182 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
183 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type UINT32.
184 */
185 TSS2_RC
186 ifapi_json_UINT32_serialize(const UINT32 in, json_object **jso)
187 {
188 *jso = json_object_new_int64(in);
189 if (*jso == NULL) {
190 LOG_ERROR("Bad value %"PRIx32 "", in);
191 return TSS2_FAPI_RC_BAD_VALUE;
192 }
193 return TSS2_RC_SUCCESS;
194 }
195
196 /** Serialize a base_type INT32 to json.
197 *
198 * @param[in] in value to be serialized.
199 * @param[out] jso pointer to the json object.
200 * @retval TSS2_RC_SUCCESS if the function call was a success.
201 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
202 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type INT32.
203 */
204 TSS2_RC
205 ifapi_json_INT32_serialize(const INT32 in, json_object **jso)
206 {
207 *jso = json_object_new_int64(in);
208 if (*jso == NULL) {
209 LOG_ERROR("Bad value %"PRIi32 "", in);
210 return TSS2_FAPI_RC_BAD_VALUE;
211 }
212 return TSS2_RC_SUCCESS;
213 }
214
215 /** Serialize a base_type UINT64 to json.
216 *
217 * @param[in] in variable to be serialized.
218 * @param[out] jso pointer to the json object.
219 * @retval TSS2_RC_SUCCESS if the function call was a success.
220 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
221 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type UINT64.
222 */
223 TSS2_RC
224 ifapi_json_UINT64_serialize(UINT64 in, json_object **jso)
225 {
226 json_object *jso1 = NULL, *jso2 = NULL;
227 if (in < 0x1000000000000) {
228 *jso = json_object_new_int64(in);
229 if (*jso == NULL) {
230 LOG_ERROR("Bad value %"PRIu32 "", (uint32_t)in);
231 return TSS2_FAPI_RC_BAD_VALUE;
232 }
233 return TSS2_RC_SUCCESS;
234 }
235
236 jso1 = json_object_new_int64(in / 0x100000000);
237 return_if_null(jso1, "Out of memory.", TSS2_FAPI_RC_MEMORY);
238
239 in %= 0x100000000;
240
241 jso2 = json_object_new_int64(in);
242 if (!jso2) json_object_put(jso1);
243 return_if_null(jso2, "Out of memory.", TSS2_FAPI_RC_MEMORY);
244
245 *jso = json_object_new_array();
246 if (!*jso) json_object_put(jso1);
247 if (!*jso) json_object_put(jso2);
248 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
249
250 json_object_array_add(*jso, jso1);
251 json_object_array_add(*jso, jso2);
252
253 return TSS2_RC_SUCCESS;
254 }
255
256 /** Serialize TPM2_GENERATED to json.
257 *
258 * @param[in] in constant to be serialized.
259 * @param[out] jso pointer to the json object.
260 * @retval TSS2_RC_SUCCESS if the function call was a success.
261 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
262 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_GENERATED.
263 */
264 TSS2_RC
265 ifapi_json_TPM2_GENERATED_serialize(const TPM2_GENERATED in, json_object **jso)
266 {
267 if (in != TPM2_GENERATED_VALUE) {
268 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
269 }
270
271 *jso = json_object_new_string("VALUE");
272 check_oom(*jso);
273
274 return TSS2_RC_SUCCESS;
275 }
276
277 /** Serialize TPM2_ALG_ID to json.
278 *
279 * @param[in] in constant to be serialized.
280 * @param[out] jso pointer to the json object.
281 * @retval TSS2_RC_SUCCESS if the function call was a success.
282 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
283 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_ALG_ID.
284 */
285 TSS2_RC
286 ifapi_json_TPM2_ALG_ID_serialize(const TPM2_ALG_ID in, json_object **jso)
287 {
288 static const struct { TPM2_ALG_ID in; const char *name; } tab[] = {
289 { TPM2_ALG_ERROR, "ERROR" },
290 { TPM2_ALG_RSA, "RSA" },
291 { TPM2_ALG_TDES, "TDES" },
292 /* We prefer SHA1 as output over SHA */
293 /* { TPM2_ALG_SHA, "SHA" },*/
294 { TPM2_ALG_SHA1, "SHA1" },
295 { TPM2_ALG_CMAC, "CMAC" },
296 { TPM2_ALG_HMAC, "HMAC" },
297 { TPM2_ALG_AES, "AES" },
298 { TPM2_ALG_MGF1, "MGF1" },
299 { TPM2_ALG_KEYEDHASH, "KEYEDHASH" },
300 { TPM2_ALG_XOR, "XOR" },
301 { TPM2_ALG_SHA256, "SHA256" },
302 { TPM2_ALG_SHA384, "SHA384" },
303 { TPM2_ALG_SHA512, "SHA512" },
304 { TPM2_ALG_NULL, "NULL" },
305 { TPM2_ALG_SM3_256, "SM3_256" },
306 { TPM2_ALG_SM4, "SM4" },
307 { TPM2_ALG_RSASSA, "RSASSA" },
308 { TPM2_ALG_RSAES, "RSAES" },
309 { TPM2_ALG_RSAPSS, "RSAPSS" },
310 { TPM2_ALG_OAEP, "OAEP" },
311 { TPM2_ALG_ECDSA, "ECDSA" },
312 { TPM2_ALG_ECDH, "ECDH" },
313 { TPM2_ALG_ECDAA, "ECDAA" },
314 { TPM2_ALG_SM2, "SM2" },
315 { TPM2_ALG_ECSCHNORR, "ECSCHNORR" },
316 { TPM2_ALG_ECMQV, "ECMQV" },
317 { TPM2_ALG_KDF1_SP800_56A, "KDF1_SP800_56A" },
318 { TPM2_ALG_KDF2, "KDF2" },
319 { TPM2_ALG_KDF1_SP800_108, "KDF1_SP800_108" },
320 { TPM2_ALG_ECC, "ECC" },
321 { TPM2_ALG_SYMCIPHER, "SYMCIPHER" },
322 { TPM2_ALG_CAMELLIA, "CAMELLIA" },
323 { TPM2_ALG_CTR, "CTR" },
324 { TPM2_ALG_OFB, "OFB" },
325 { TPM2_ALG_CBC, "CBC" },
326 { TPM2_ALG_CFB, "CFB" },
327 { TPM2_ALG_ECB, "ECB" },
328 };
329
330 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
331 if (tab[i].in == in) {
332 *jso = json_object_new_string(tab[i].name);
333 check_oom(*jso);
334 return TSS2_RC_SUCCESS;
335 }
336 }
337 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
338 }
339
340 /** Serialize TPM2_ECC_CURVE to json.
341 *
342 * @param[in] in constant to be serialized.
343 * @param[out] jso pointer to the json object.
344 * @retval TSS2_RC_SUCCESS if the function call was a success.
345 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
346 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_ECC_CURVE.
347 */
348 TSS2_RC
349 ifapi_json_TPM2_ECC_CURVE_serialize(const TPM2_ECC_CURVE in, json_object **jso)
350 {
351 static const struct { TPM2_ECC_CURVE in; char *name; } tab[] = {
352 { TPM2_ECC_NONE, "NONE" },
353 { TPM2_ECC_NIST_P192, "NIST_P192" },
354 { TPM2_ECC_NIST_P224, "NIST_P224" },
355 { TPM2_ECC_NIST_P256, "NIST_P256" },
356 { TPM2_ECC_NIST_P384, "NIST_P384" },
357 { TPM2_ECC_NIST_P521, "NIST_P521" },
358 { TPM2_ECC_BN_P256, "BN_P256" },
359 { TPM2_ECC_BN_P638, "BN_P638" },
360 { TPM2_ECC_SM2_P256, "SM2_P256" },
361 };
362
363 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
364 if (tab[i].in == in) {
365 *jso = json_object_new_string(tab[i].name);
366 check_oom(*jso);
367 return TSS2_RC_SUCCESS;
368 }
369 }
370 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
371 }
372
373 /** Serialize TPM2_CC to json.
374 *
375 * @param[in] in constant to be serialized.
376 * @param[out] jso pointer to the json object.
377 * @retval TSS2_RC_SUCCESS if the function call was a success.
378 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
379 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_CC.
380 */
381 TSS2_RC
382 ifapi_json_TPM2_CC_serialize(const TPM2_CC in, json_object **jso)
383 {
384 static const struct { TPM2_CC in; char *name; } tab[] = {
385 /* We don't want to return FIRST but the actual value */
386 /* { TPM2_CC_FIRST, "FIRST" }, */
387 { TPM2_CC_NV_UndefineSpaceSpecial, "NV_UndefineSpaceSpecial" },
388 { TPM2_CC_EvictControl, "EvictControl" },
389 { TPM2_CC_HierarchyControl, "HierarchyControl" },
390 { TPM2_CC_NV_UndefineSpace, "NV_UndefineSpace" },
391 { TPM2_CC_ChangeEPS, "ChangeEPS" },
392 { TPM2_CC_ChangePPS, "ChangePPS" },
393 { TPM2_CC_Clear, "Clear" },
394 { TPM2_CC_ClearControl, "ClearControl" },
395 { TPM2_CC_ClockSet, "ClockSet" },
396 { TPM2_CC_HierarchyChangeAuth, "HierarchyChangeAuth" },
397 { TPM2_CC_NV_DefineSpace, "NV_DefineSpace" },
398 { TPM2_CC_PCR_Allocate, "PCR_Allocate" },
399 { TPM2_CC_PCR_SetAuthPolicy, "PCR_SetAuthPolicy" },
400 { TPM2_CC_PP_Commands, "PP_Commands" },
401 { TPM2_CC_SetPrimaryPolicy, "SetPrimaryPolicy" },
402 { TPM2_CC_FieldUpgradeStart, "FieldUpgradeStart" },
403 { TPM2_CC_ClockRateAdjust, "ClockRateAdjust" },
404 { TPM2_CC_CreatePrimary, "CreatePrimary" },
405 { TPM2_CC_NV_GlobalWriteLock, "NV_GlobalWriteLock" },
406 { TPM2_CC_GetCommandAuditDigest, "GetCommandAuditDigest" },
407 { TPM2_CC_NV_Increment, "NV_Increment" },
408 { TPM2_CC_NV_SetBits, "NV_SetBits" },
409 { TPM2_CC_NV_Extend, "NV_Extend" },
410 { TPM2_CC_NV_Write, "NV_Write" },
411 { TPM2_CC_NV_WriteLock, "NV_WriteLock" },
412 { TPM2_CC_DictionaryAttackLockReset, "DictionaryAttackLockReset" },
413 { TPM2_CC_DictionaryAttackParameters, "DictionaryAttackParameters" },
414 { TPM2_CC_NV_ChangeAuth, "NV_ChangeAuth" },
415 { TPM2_CC_PCR_Event, "PCR_Event" },
416 { TPM2_CC_PCR_Reset, "PCR_Reset" },
417 { TPM2_CC_SequenceComplete, "SequenceComplete" },
418 { TPM2_CC_SetAlgorithmSet, "SetAlgorithmSet" },
419 { TPM2_CC_SetCommandCodeAuditStatus, "SetCommandCodeAuditStatus" },
420 { TPM2_CC_FieldUpgradeData, "FieldUpgradeData" },
421 { TPM2_CC_IncrementalSelfTest, "IncrementalSelfTest" },
422 { TPM2_CC_SelfTest, "SelfTest" },
423 { TPM2_CC_Startup, "Startup" },
424 { TPM2_CC_Shutdown, "Shutdown" },
425 { TPM2_CC_StirRandom, "StirRandom" },
426 { TPM2_CC_ActivateCredential, "ActivateCredential" },
427 { TPM2_CC_Certify, "Certify" },
428 { TPM2_CC_PolicyNV, "PolicyNV" },
429 { TPM2_CC_CertifyCreation, "CertifyCreation" },
430 { TPM2_CC_Duplicate, "Duplicate" },
431 { TPM2_CC_GetTime, "GetTime" },
432 { TPM2_CC_GetSessionAuditDigest, "GetSessionAuditDigest" },
433 { TPM2_CC_NV_Read, "NV_Read" },
434 { TPM2_CC_NV_ReadLock, "NV_ReadLock" },
435 { TPM2_CC_ObjectChangeAuth, "ObjectChangeAuth" },
436 { TPM2_CC_PolicySecret, "PolicySecret" },
437 { TPM2_CC_Rewrap, "Rewrap" },
438 { TPM2_CC_Create, "Create" },
439 { TPM2_CC_ECDH_ZGen, "ECDH_ZGen" },
440 { TPM2_CC_HMAC, "HMAC" },
441 { TPM2_CC_Import, "Import" },
442 { TPM2_CC_Load, "Load" },
443 { TPM2_CC_Quote, "Quote" },
444 { TPM2_CC_RSA_Decrypt, "RSA_Decrypt" },
445 { TPM2_CC_HMAC_Start, "HMAC_Start" },
446 { TPM2_CC_SequenceUpdate, "SequenceUpdate" },
447 { TPM2_CC_Sign, "Sign" },
448 { TPM2_CC_Unseal, "Unseal" },
449 { TPM2_CC_PolicySigned, "PolicySigned" },
450 { TPM2_CC_ContextLoad, "ContextLoad" },
451 { TPM2_CC_ContextSave, "ContextSave" },
452 { TPM2_CC_ECDH_KeyGen, "ECDH_KeyGen" },
453 { TPM2_CC_EncryptDecrypt, "EncryptDecrypt" },
454 { TPM2_CC_FlushContext, "FlushContext" },
455 { TPM2_CC_LoadExternal, "LoadExternal" },
456 { TPM2_CC_MakeCredential, "MakeCredential" },
457 { TPM2_CC_NV_ReadPublic, "NV_ReadPublic" },
458 { TPM2_CC_PolicyAuthorize, "PolicyAuthorize" },
459 { TPM2_CC_PolicyAuthValue, "PolicyAuthValue" },
460 { TPM2_CC_PolicyCommandCode, "PolicyCommandCode" },
461 { TPM2_CC_PolicyCounterTimer, "PolicyCounterTimer" },
462 { TPM2_CC_PolicyCpHash, "PolicyCpHash" },
463 { TPM2_CC_PolicyLocality, "PolicyLocality" },
464 { TPM2_CC_PolicyNameHash, "PolicyNameHash" },
465 { TPM2_CC_PolicyOR, "PolicyOR" },
466 { TPM2_CC_PolicyTicket, "PolicyTicket" },
467 { TPM2_CC_ReadPublic, "ReadPublic" },
468 { TPM2_CC_RSA_Encrypt, "RSA_Encrypt" },
469 { TPM2_CC_StartAuthSession, "StartAuthSession" },
470 { TPM2_CC_VerifySignature, "VerifySignature" },
471 { TPM2_CC_ECC_Parameters, "ECC_Parameters" },
472 { TPM2_CC_FirmwareRead, "FirmwareRead" },
473 { TPM2_CC_GetCapability, "GetCapability" },
474 { TPM2_CC_GetRandom, "GetRandom" },
475 { TPM2_CC_GetTestResult, "GetTestResult" },
476 { TPM2_CC_Hash, "Hash" },
477 { TPM2_CC_PCR_Read, "PCR_Read" },
478 { TPM2_CC_PolicyPCR, "PolicyPCR" },
479 { TPM2_CC_PolicyRestart, "PolicyRestart" },
480 { TPM2_CC_ReadClock, "ReadClock" },
481 { TPM2_CC_PCR_Extend, "PCR_Extend" },
482 { TPM2_CC_PCR_SetAuthValue, "PCR_SetAuthValue" },
483 { TPM2_CC_NV_Certify, "NV_Certify" },
484 { TPM2_CC_EventSequenceComplete, "EventSequenceComplete" },
485 { TPM2_CC_HashSequenceStart, "HashSequenceStart" },
486 { TPM2_CC_PolicyPhysicalPresence, "PolicyPhysicalPresence" },
487 { TPM2_CC_PolicyDuplicationSelect, "PolicyDuplicationSelect" },
488 { TPM2_CC_PolicyGetDigest, "PolicyGetDigest" },
489 { TPM2_CC_TestParms, "TestParms" },
490 { TPM2_CC_Commit, "Commit" },
491 { TPM2_CC_PolicyPassword, "PolicyPassword" },
492 { TPM2_CC_ZGen_2Phase, "ZGen_2Phase" },
493 { TPM2_CC_EC_Ephemeral, "EC_Ephemeral" },
494 { TPM2_CC_PolicyNvWritten, "PolicyNvWritten" },
495 { TPM2_CC_PolicyTemplate, "PolicyTemplate" },
496 { TPM2_CC_CreateLoaded, "CreateLoaded" },
497 { TPM2_CC_PolicyAuthorizeNV, "PolicyAuthorizeNV" },
498 { TPM2_CC_EncryptDecrypt2, "EncryptDecrypt2" },
499 /* We don't want to return LAST but the actual value */
500 /* { TPM2_CC_LAST, "LAST" }, */
501 { TPM2_CC_Vendor_TCG_Test, "Vendor_TCG_Test" },
502 };
503
504 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
505 if (tab[i].in == in) {
506 *jso = json_object_new_string(tab[i].name);
507 check_oom(*jso);
508 return TSS2_RC_SUCCESS;
509 }
510 }
511 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
512 }
513
514 /** Serialize TPM2_EO to json.
515 *
516 * @param[in] in constant to be serialized.
517 * @param[out] jso pointer to the json object.
518 * @retval TSS2_RC_SUCCESS if the function call was a success.
519 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
520 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_EO.
521 */
522 TSS2_RC
523 ifapi_json_TPM2_EO_serialize(const TPM2_EO in, json_object **jso)
524 {
525 static const struct { TPM2_EO in; char *name; } tab[] = {
526 { TPM2_EO_EQ, "EQ" },
527 { TPM2_EO_NEQ, "TPM2_EO_NEQ" },
528 { TPM2_EO_SIGNED_GT, "SIGNED_GT" },
529 { TPM2_EO_UNSIGNED_GT, "UNSIGNED_GT" },
530 { TPM2_EO_SIGNED_LT, "SIGNED_LT" },
531 { TPM2_EO_UNSIGNED_LT, "UNSIGNED_LT" },
532 { TPM2_EO_SIGNED_GE, "SIGNED_GE" },
533 { TPM2_EO_UNSIGNED_GE, "UNSIGNED_GE" },
534 { TPM2_EO_SIGNED_LE, "SIGNED_LE" },
535 { TPM2_EO_UNSIGNED_LE, "UNSIGNED_LE" },
536 { TPM2_EO_BITSET, "BITSET" },
537 { TPM2_EO_BITCLEAR, "BITCLEAR" },
538 };
539
540 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
541 if (tab[i].in == in) {
542 *jso = json_object_new_string(tab[i].name);
543 check_oom(*jso);
544 return TSS2_RC_SUCCESS;
545 }
546 }
547 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
548 }
549
550 /** Serialize TPM2_ST to json.
551 *
552 * @param[in] in constant to be serialized.
553 * @param[out] jso pointer to the json object.
554 * @retval TSS2_RC_SUCCESS if the function call was a success.
555 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
556 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_ST.
557 */
558 TSS2_RC
559 ifapi_json_TPM2_ST_serialize(const TPM2_ST in, json_object **jso)
560 {
561 static const struct { TPM2_ST in; char *name; } tab[] = {
562 { TPM2_ST_RSP_COMMAND, "RSP_COMMAND" },
563 { TPM2_ST_NULL, "NULL" },
564 { TPM2_ST_NO_SESSIONS, "NO_SESSIONS" },
565 { TPM2_ST_SESSIONS, "SESSIONS" },
566 { TPM2_ST_ATTEST_NV, "ATTEST_NV" },
567 { TPM2_ST_ATTEST_COMMAND_AUDIT, "ATTEST_COMMAND_AUDIT" },
568 { TPM2_ST_ATTEST_SESSION_AUDIT, "ATTEST_SESSION_AUDIT" },
569 { TPM2_ST_ATTEST_CERTIFY, "ATTEST_CERTIFY" },
570 { TPM2_ST_ATTEST_QUOTE, "ATTEST_QUOTE" },
571 { TPM2_ST_ATTEST_TIME, "ATTEST_TIME" },
572 { TPM2_ST_ATTEST_CREATION, "ATTEST_CREATION" },
573 { TPM2_ST_CREATION, "CREATION" },
574 { TPM2_ST_VERIFIED, "VERIFIED" },
575 { TPM2_ST_AUTH_SECRET, "AUTH_SECRET" },
576 { TPM2_ST_HASHCHECK, "HASHCHECK" },
577 { TPM2_ST_AUTH_SIGNED, "AUTH_SIGNED" },
578 { TPM2_ST_FU_MANIFEST, "FU_MANIFEST" },
579 };
580
581 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
582 if (tab[i].in == in) {
583 *jso = json_object_new_string(tab[i].name);
584 check_oom(*jso);
585 return TSS2_RC_SUCCESS;
586 }
587 }
588 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
589 }
590
591 /** Serialize TPM2_CAP to json.
592 *
593 * @param[in] in constant to be serialized.
594 * @param[out] jso pointer to the json object.
595 * @retval TSS2_RC_SUCCESS if the function call was a success.
596 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
597 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_CAP.
598 */
599 TSS2_RC
600 ifapi_json_TPM2_CAP_serialize(const TPM2_CAP in, json_object **jso)
601 {
602 static const struct { TPM2_CAP in; char *name; } tab[] = {
603 { TPM2_CAP_ALGS, "ALGS" },
604 { TPM2_CAP_HANDLES, "HANDLES" },
605 { TPM2_CAP_COMMANDS, "COMMANDS" },
606 { TPM2_CAP_PP_COMMANDS, "PP_COMMANDS" },
607 { TPM2_CAP_AUDIT_COMMANDS, "AUDIT_COMMANDS" },
608 { TPM2_CAP_PCRS, "PCRS" },
609 { TPM2_CAP_TPM_PROPERTIES, "TPM_PROPERTIES" },
610 { TPM2_CAP_PCR_PROPERTIES, "PCR_PROPERTIES" },
611 { TPM2_CAP_ECC_CURVES, "ECC_CURVES" },
612 { TPM2_CAP_LAST, "LAST" },
613 { TPM2_CAP_VENDOR_PROPERTY, "VENDOR_PROPERTY" },
614 };
615
616 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
617 if (tab[i].in == in) {
618 *jso = json_object_new_string(tab[i].name);
619 check_oom(*jso);
620 return TSS2_RC_SUCCESS;
621 }
622 }
623 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
624 }
625
626 /** Serialize TPM2_PT to json.
627 *
628 * @param[in] in constant to be serialized.
629 * @param[out] jso pointer to the json object.
630 * @retval TSS2_RC_SUCCESS if the function call was a success.
631 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
632 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_PT.
633 */
634 TSS2_RC
635 ifapi_json_TPM2_PT_serialize(const TPM2_PT in, json_object **jso)
636 {
637 static const struct { TPM2_PT in; char *name; } tab[] = {
638 { TPM2_PT_NONE, "NONE" },
639 { TPM2_PT_GROUP, "GROUP" },
640 { TPM2_PT_FIXED, "FIXED" },
641 { TPM2_PT_FAMILY_INDICATOR, "FAMILY_INDICATOR" },
642 { TPM2_PT_LEVEL, "LEVEL" },
643 { TPM2_PT_REVISION, "REVISION" },
644 { TPM2_PT_DAY_OF_YEAR, "DAY_OF_YEAR" },
645 { TPM2_PT_YEAR, "YEAR" },
646 { TPM2_PT_MANUFACTURER, "MANUFACTURER" },
647 { TPM2_PT_VENDOR_STRING_1, "VENDOR_STRING_1" },
648 { TPM2_PT_VENDOR_STRING_2, "VENDOR_STRING_2" },
649 { TPM2_PT_VENDOR_STRING_3, "VENDOR_STRING_3" },
650 { TPM2_PT_VENDOR_STRING_4, "VENDOR_STRING_4" },
651 { TPM2_PT_VENDOR_TPM_TYPE, "VENDOR_TPM_TYPE" },
652 { TPM2_PT_FIRMWARE_VERSION_1, "FIRMWARE_VERSION_1" },
653 { TPM2_PT_FIRMWARE_VERSION_2, "FIRMWARE_VERSION_2" },
654 { TPM2_PT_INPUT_BUFFER, "INPUT_BUFFER" },
655 { TPM2_PT_HR_TRANSIENT_MIN, "HR_TRANSIENT_MIN" },
656 { TPM2_PT_HR_PERSISTENT_MIN, "HR_PERSISTENT_MIN" },
657 { TPM2_PT_HR_LOADED_MIN, "HR_LOADED_MIN" },
658 { TPM2_PT_ACTIVE_SESSIONS_MAX, "ACTIVE_SESSIONS_MAX" },
659 { TPM2_PT_PCR_COUNT, "PCR_COUNT" },
660 { TPM2_PT_PCR_SELECT_MIN, "PCR_SELECT_MIN" },
661 { TPM2_PT_CONTEXT_GAP_MAX, "CONTEXT_GAP_MAX" },
662 { TPM2_PT_NV_COUNTERS_MAX, "NV_COUNTERS_MAX" },
663 { TPM2_PT_NV_INDEX_MAX, "NV_INDEX_MAX" },
664 { TPM2_PT_MEMORY, "MEMORY" },
665 { TPM2_PT_CLOCK_UPDATE, "CLOCK_UPDATE" },
666 { TPM2_PT_CONTEXT_HASH, "CONTEXT_HASH" },
667 { TPM2_PT_CONTEXT_SYM, "CONTEXT_SYM" },
668 { TPM2_PT_CONTEXT_SYM_SIZE, "CONTEXT_SYM_SIZE" },
669 { TPM2_PT_ORDERLY_COUNT, "ORDERLY_COUNT" },
670 { TPM2_PT_MAX_COMMAND_SIZE, "MAX_COMMAND_SIZE" },
671 { TPM2_PT_MAX_RESPONSE_SIZE, "MAX_RESPONSE_SIZE" },
672 { TPM2_PT_MAX_DIGEST, "MAX_DIGEST" },
673 { TPM2_PT_MAX_OBJECT_CONTEXT, "MAX_OBJECT_CONTEXT" },
674 { TPM2_PT_MAX_SESSION_CONTEXT, "MAX_SESSION_CONTEXT" },
675 { TPM2_PT_PS_FAMILY_INDICATOR, "PS_FAMILY_INDICATOR" },
676 { TPM2_PT_PS_LEVEL, "PS_LEVEL" },
677 { TPM2_PT_PS_REVISION, "PS_REVISION" },
678 { TPM2_PT_PS_DAY_OF_YEAR, "PS_DAY_OF_YEAR" },
679 { TPM2_PT_PS_YEAR, "PS_YEAR" },
680 { TPM2_PT_SPLIT_MAX, "SPLIT_MAX" },
681 { TPM2_PT_TOTAL_COMMANDS, "TOTAL_COMMANDS" },
682 { TPM2_PT_LIBRARY_COMMANDS, "LIBRARY_COMMANDS" },
683 { TPM2_PT_VENDOR_COMMANDS, "VENDOR_COMMANDS" },
684 { TPM2_PT_NV_BUFFER_MAX, "NV_BUFFER_MAX" },
685 { TPM2_PT_MODES, "MODES" },
686 { TPM2_PT_MAX_CAP_BUFFER, "MAX_CAP_BUFFER" },
687 { TPM2_PT_VAR, "VAR" },
688 { TPM2_PT_PERMANENT, "PERMANENT" },
689 { TPM2_PT_STARTUP_CLEAR, "STARTUP_CLEAR" },
690 { TPM2_PT_HR_NV_INDEX, "HR_NV_INDEX" },
691 { TPM2_PT_HR_LOADED, "HR_LOADED" },
692 { TPM2_PT_HR_LOADED_AVAIL, "HR_LOADED_AVAIL" },
693 { TPM2_PT_HR_ACTIVE, "HR_ACTIVE" },
694 { TPM2_PT_HR_ACTIVE_AVAIL, "HR_ACTIVE_AVAIL" },
695 { TPM2_PT_HR_TRANSIENT_AVAIL, "HR_TRANSIENT_AVAIL" },
696 { TPM2_PT_HR_PERSISTENT, "HR_PERSISTENT" },
697 { TPM2_PT_HR_PERSISTENT_AVAIL, "HR_PERSISTENT_AVAIL" },
698 { TPM2_PT_NV_COUNTERS, "NV_COUNTERS" },
699 { TPM2_PT_NV_COUNTERS_AVAIL, "NV_COUNTERS_AVAIL" },
700 { TPM2_PT_ALGORITHM_SET, "ALGORITHM_SET" },
701 { TPM2_PT_LOADED_CURVES, "LOADED_CURVES" },
702 { TPM2_PT_LOCKOUT_COUNTER, "LOCKOUT_COUNTER" },
703 { TPM2_PT_MAX_AUTH_FAIL, "MAX_AUTH_FAIL" },
704 { TPM2_PT_LOCKOUT_INTERVAL, "LOCKOUT_INTERVAL" },
705 { TPM2_PT_LOCKOUT_RECOVERY, "LOCKOUT_RECOVERY" },
706 { TPM2_PT_NV_WRITE_RECOVERY, "NV_WRITE_RECOVERY" },
707 { TPM2_PT_AUDIT_COUNTER_0, "AUDIT_COUNTER_0" },
708 { TPM2_PT_AUDIT_COUNTER_1, "AUDIT_COUNTER_1" },
709 };
710
711 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
712 if (tab[i].in == in) {
713 *jso = json_object_new_string(tab[i].name);
714 check_oom(*jso);
715 return TSS2_RC_SUCCESS;
716 }
717 }
718 return_error2(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant: %"PRIx32, in);
719 }
720
721 /** Serialize TPM2_PT_PCR to json.
722 *
723 * @param[in] in constant to be serialized.
724 * @param[out] jso pointer to the json object.
725 * @retval TSS2_RC_SUCCESS if the function call was a success.
726 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
727 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_PT_PCR.
728 */
729 TSS2_RC
730 ifapi_json_TPM2_PT_PCR_serialize(const TPM2_PT_PCR in, json_object **jso)
731 {
732 static const struct { TPM2_PT_PCR in; char *name; } tab[] = {
733 { TPM2_PT_PCR_SAVE, "SAVE" },
734 { TPM2_PT_PCR_EXTEND_L0, "EXTEND_L0" },
735 { TPM2_PT_PCR_RESET_L0, "RESET_L0" },
736 { TPM2_PT_PCR_EXTEND_L1, "EXTEND_L1" },
737 { TPM2_PT_PCR_RESET_L1, "RESET_L1" },
738 { TPM2_PT_PCR_EXTEND_L2, "EXTEND_L2" },
739 { TPM2_PT_PCR_RESET_L2, "RESET_L2" },
740 { TPM2_PT_PCR_EXTEND_L3, "EXTEND_L3" },
741 { TPM2_PT_PCR_RESET_L3, "RESET_L3" },
742 { TPM2_PT_PCR_EXTEND_L4, "EXTEND_L4" },
743 { TPM2_PT_PCR_RESET_L4, "RESET_L4" },
744 { TPM2_PT_PCR_NO_INCREMENT, "NO_INCREMENT" },
745 { TPM2_PT_PCR_DRTM_RESET, "DRTM_RESET" },
746 { TPM2_PT_PCR_POLICY, "POLICY" },
747 { TPM2_PT_PCR_AUTH, "AUTH" },
748 };
749
750 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
751 if (tab[i].in == in) {
752 *jso = json_object_new_string(tab[i].name);
753 check_oom(*jso);
754 return TSS2_RC_SUCCESS;
755 }
756 }
757 return_error2(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant: %"PRIx32, in);
758 }
759
760 /** Serialize value of type TPM2_HANDLE to json.
761 *
762 * @param[in] in value to be serialized.
763 * @param[out] jso pointer to the json object.
764 * @retval TSS2_RC_SUCCESS if the function call was a success.
765 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
766 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2_HANDLE.
767 */
768 TSS2_RC
769 ifapi_json_TPM2_HANDLE_serialize(const TPM2_HANDLE in, json_object **jso)
770 {
771 *jso = json_object_new_int(in);
772 if (*jso == NULL) {
773 LOG_ERROR("Bad value %"PRIx32 "", in);
774 return TSS2_FAPI_RC_BAD_VALUE;
775 }
776 return TSS2_RC_SUCCESS;
777 }
778 /** Serialize a TPMA_ALGORITHM to json.
779 *
780 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
781 *
782 * @param[in] in value to be serialized.
783 * @param[out] jso pointer to the json object.
784 * @retval TSS2_RC_SUCCESS if the function call was a success.
785 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
786 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPMA_ALGORITHM.
787 */
788 TSS2_RC
789 ifapi_json_TPMA_ALGORITHM_serialize(const TPMA_ALGORITHM in, json_object **jso)
790 {
791 static const struct { TPMA_ALGORITHM in; char *name; } tab[] = {
792 { TPMA_ALGORITHM_ASYMMETRIC, "asymmetric" },
793 { TPMA_ALGORITHM_SYMMETRIC, "symmetric" },
794 { TPMA_ALGORITHM_HASH, "hash" },
795 { TPMA_ALGORITHM_OBJECT, "object" },
796 { TPMA_ALGORITHM_SIGNING, "signing" },
797 { TPMA_ALGORITHM_ENCRYPTING, "encrypting" },
798 { TPMA_ALGORITHM_METHOD, "method" },
799 };
800
801 UINT32 input;
802 input = (UINT32) in;
803 json_object *jso_bit;
804 if (*jso == NULL) {
805 *jso = json_object_new_object();
806 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
807 }
808 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
809 if (tab[i].in & input)
810 jso_bit = json_object_new_int(1);
811 else
812 jso_bit = json_object_new_int(0);
813 return_if_null(jso_bit, "Out of memory.", TSS2_FAPI_RC_MEMORY);
814
815 json_object_object_add(*jso, tab[i].name, jso_bit);
816 }
817 return TSS2_RC_SUCCESS;
818 }
819
820 /** Serialize a TPMA_OBJECT to json.
821 *
822 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
823 *
824 * @param[in] in value to be serialized.
825 * @param[out] jso pointer to the json object.
826 * @retval TSS2_RC_SUCCESS if the function call was a success.
827 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
828 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPMA_OBJECT.
829 */
830 TSS2_RC
831 ifapi_json_TPMA_OBJECT_serialize(const TPMA_OBJECT in, json_object **jso)
832 {
833 static const struct { TPMA_OBJECT in; char *name; } tab[] = {
834 { TPMA_OBJECT_FIXEDTPM, "fixedTPM" },
835 { TPMA_OBJECT_STCLEAR, "stClear" },
836 { TPMA_OBJECT_FIXEDPARENT, "fixedParent" },
837 { TPMA_OBJECT_SENSITIVEDATAORIGIN, "sensitiveDataOrigin" },
838 { TPMA_OBJECT_USERWITHAUTH, "userWithAuth" },
839 { TPMA_OBJECT_ADMINWITHPOLICY, "adminWithPolicy" },
840 { TPMA_OBJECT_NODA, "noDA" },
841 { TPMA_OBJECT_ENCRYPTEDDUPLICATION, "encryptedDuplication" },
842 { TPMA_OBJECT_RESTRICTED, "restricted" },
843 { TPMA_OBJECT_DECRYPT, "decrypt" },
844 { TPMA_OBJECT_SIGN_ENCRYPT, "sign" },
845 };
846 UINT32 input;
847 input = (UINT32) in;
848 json_object *jso_bit;
849 if (*jso == NULL) {
850 *jso = json_object_new_object();
851 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
852 }
853 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
854 if (tab[i].in & input)
855 jso_bit = json_object_new_int(1);
856 else
857 jso_bit = json_object_new_int(0);
858 return_if_null(jso_bit, "Out of memory.", TSS2_FAPI_RC_MEMORY);
859
860 json_object_object_add(*jso, tab[i].name, jso_bit);
861 }
862 return TSS2_RC_SUCCESS;
863 }
864
865 /** Serialize a TPMA_LOCALITY to json.
866 *
867 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
868 *
869 * @param[in] in value to be serialized.
870 * @param[out] jso pointer to the json object.
871 * @retval TSS2_RC_SUCCESS if the function call was a success.
872 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
873 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPMA_LOCALITY.
874 */
875 TSS2_RC
876 ifapi_json_TPMA_LOCALITY_serialize(const TPMA_LOCALITY in, json_object **jso)
877 {
878 static const struct { TPMA_LOCALITY in; char *name; } tab[] = {
879 { TPMA_LOCALITY_TPM2_LOC_ZERO, "ZERO" },
880 { TPMA_LOCALITY_TPM2_LOC_ONE, "ONE" },
881 { TPMA_LOCALITY_TPM2_LOC_TWO, "TWO" },
882 { TPMA_LOCALITY_TPM2_LOC_THREE, "THREE" },
883 { TPMA_LOCALITY_TPM2_LOC_FOUR, "FOUR" },
884 };
885
886 UINT8 input;
887 input = (UINT8) in;
888 json_object *jso_bit;
889 json_object *jso_bit_idx;
890 if (*jso == NULL) {
891 *jso = json_object_new_object();
892 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
893 }
894 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
895 if (tab[i].in & input)
896 jso_bit = json_object_new_int(1);
897 else
898 jso_bit = json_object_new_int(0);
899 return_if_null(jso_bit, "Out of memory.", TSS2_FAPI_RC_MEMORY);
900
901 json_object_object_add(*jso, tab[i].name, jso_bit);
902 }
903 jso_bit_idx = json_object_new_int64((TPMA_LOCALITY_EXTENDED_MASK & input) >>
904 5);
905 return_if_null(jso_bit_idx, "Out of memory.", TSS2_FAPI_RC_MEMORY);
906
907 json_object_object_add(*jso, "Extended", jso_bit_idx);
908
909 return TSS2_RC_SUCCESS;
910 }
911
912 /** Serialize a TPMA_CC to json.
913 *
914 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
915 *
916 * @param[in] in value to be serialized.
917 * @param[out] jso pointer to the json object.
918 * @retval TSS2_RC_SUCCESS if the function call was a success.
919 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
920 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPMA_CC.
921 */
922 TSS2_RC
923 ifapi_json_TPMA_CC_serialize(const TPMA_CC in, json_object **jso)
924 {
925 static const struct { TPMA_CC in; char *name; } tab[] = {
926 { TPMA_CC_NV, "nv" },
927 { TPMA_CC_EXTENSIVE, "extensive" },
928 { TPMA_CC_FLUSHED, "flushed" },
929 { TPMA_CC_RHANDLE, "rHandle" },
930 { TPMA_CC_V, "V" },
931 };
932 TPM2_CC input;
933 input = (TPM2_CC) in;
934 json_object *jso_bit;
935 json_object *jso_bit_idx;
936 if (*jso == NULL) {
937 *jso = json_object_new_object();
938 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
939 }
940 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
941 if (tab[i].in & input)
942 jso_bit = json_object_new_int(1);
943 else
944 jso_bit = json_object_new_int(0);
945 return_if_null(jso_bit, "Out of memory.", TSS2_FAPI_RC_MEMORY);
946
947 json_object_object_add(*jso, tab[i].name, jso_bit);
948 }
949 jso_bit_idx = json_object_new_int64((TPMA_CC_COMMANDINDEX_MASK & input) >> 0);
950 return_if_null(jso_bit_idx, "Out of memory.", TSS2_FAPI_RC_MEMORY);
951
952 json_object_object_add(*jso, "commandIndex", jso_bit_idx);
953
954 jso_bit_idx = json_object_new_int64((TPMA_CC_CHANDLES_MASK & input) >> 25);
955 return_if_null(jso_bit_idx, "Out of memory.", TSS2_FAPI_RC_MEMORY);
956
957 json_object_object_add(*jso, "cHandles", jso_bit_idx);
958
959 jso_bit_idx = json_object_new_int64((TPMA_CC_RES_MASK & input) >> 30);
960 return_if_null(jso_bit_idx, "Out of memory.", TSS2_FAPI_RC_MEMORY);
961
962 json_object_object_add(*jso, "Res", jso_bit_idx);
963
964 return TSS2_RC_SUCCESS;
965 }
966
967 /** Serialize TPMI_YES_NO to json.
968 *
969 * @param[in] in variable to be serialized.
970 * @param[out] jso pointer to the json object.
971 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
972 * the function.
973 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
974 */
975 TSS2_RC
976 ifapi_json_TPMI_YES_NO_serialize(const TPMI_YES_NO in, json_object **jso)
977 {
978 if (in == YES) {
979 *jso = json_object_new_string("YES");
980 } else if (in == NO) {
981 *jso = json_object_new_string("NO");
982 } else {
983 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
984 }
985 check_oom(*jso);
986 return TSS2_RC_SUCCESS;
987 }
988
989 /** Serialize TPMI_RH_HIERARCHY to json.
990 *
991 * @param[in] in variable to be serialized.
992 * @param[out] jso pointer to the json object.
993 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
994 * the function.
995 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
996 */
997 TSS2_RC
998 ifapi_json_TPMI_RH_HIERARCHY_serialize(const TPMI_RH_HIERARCHY in,
999 json_object **jso)
1000 {
1001 static const struct { TPMI_RH_HIERARCHY in; char *name; } tab[] = {
1002 { TPM2_RH_OWNER, "OWNER" },
1003 { TPM2_RH_PLATFORM, "PLATFORM" },
1004 { TPM2_RH_ENDORSEMENT, "ENDORSEMENT" },
1005 { TPM2_RH_NULL, "NULL" },
1006 };
1007
1008 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
1009 if (tab[i].in == in) {
1010 *jso = json_object_new_string(tab[i].name);
1011 check_oom(*jso);
1012 return TSS2_RC_SUCCESS;
1013 }
1014 }
1015 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
1016 }
1017
1018 /** Serialize value of type TPMI_RH_NV_INDEX to json.
1019 *
1020 * @param[in] in value to be serialized.
1021 * @param[out] jso pointer to the json object.
1022 * @retval TSS2_RC_SUCCESS if the function call was a success.
1023 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1024 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMI_RH_NV_INDEX.
1025 *
1026 */
1027 TSS2_RC
1028 ifapi_json_TPMI_RH_NV_INDEX_serialize(const TPMI_RH_NV_INDEX in,
1029 json_object **jso)
1030 {
1031 if (in >= TPM2_NV_INDEX_FIRST && in <= TPM2_NV_INDEX_LAST) {
1032 *jso = json_object_new_int64(in);
1033 } else {
1034 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
1035 }
1036 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1037
1038 return TSS2_RC_SUCCESS;
1039 }
1040
1041 /** Serialize TPMI_ALG_HASH to json.
1042 *
1043 * @param[in] in variable to be serialized.
1044 * @param[out] jso pointer to the json object.
1045 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1046 * the function.
1047 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1048 */
1049 TSS2_RC
1050 ifapi_json_TPMI_ALG_HASH_serialize(const TPMI_ALG_HASH in, json_object **jso)
1051 {
1052 CHECK_IN_LIST(TPMI_ALG_HASH, in, TPM2_ALG_SHA1, TPM2_ALG_SHA256, TPM2_ALG_SHA384,
1053 TPM2_ALG_SHA512, TPM2_ALG_NULL);
1054 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
1055 }
1056
1057 /** Serialize TPMI_ALG_SYM_OBJECT to json.
1058 *
1059 * @param[in] in variable to be serialized.
1060 * @param[out] jso pointer to the json object.
1061 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1062 * the function.
1063 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1064 */
1065 TSS2_RC
1066 ifapi_json_TPMI_ALG_SYM_OBJECT_serialize(const TPMI_ALG_SYM_OBJECT in,
1067 json_object **jso)
1068 {
1069 CHECK_IN_LIST(TPMI_ALG_SYM_OBJECT, in, TPM2_ALG_AES, TPM2_ALG_NULL);
1070 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
1071 }
1072
1073 /** Serialize TPMI_ALG_SYM_MODE to json.
1074 *
1075 * @param[in] in variable to be serialized.
1076 * @param[out] jso pointer to the json object.
1077 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1078 * the function.
1079 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1080 */
1081 TSS2_RC
1082 ifapi_json_TPMI_ALG_SYM_MODE_serialize(const TPMI_ALG_SYM_MODE in,
1083 json_object **jso)
1084 {
1085 CHECK_IN_LIST(TPMI_ALG_SYM_MODE, in, TPM2_ALG_CTR, TPM2_ALG_OFB,
1086 TPM2_ALG_CBC, TPM2_ALG_CFB, TPM2_ALG_ECB, TPM2_ALG_NULL);
1087 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
1088 }
1089
1090 /** Serialize TPMI_ALG_KDF to json.
1091 *
1092 * @param[in] in variable to be serialized.
1093 * @param[out] jso pointer to the json object.
1094 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1095 * the function.
1096 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1097 */
1098 TSS2_RC
1099 ifapi_json_TPMI_ALG_KDF_serialize(const TPMI_ALG_KDF in, json_object **jso)
1100 {
1101 CHECK_IN_LIST(TPMI_ALG_KDF, in, TPM2_ALG_MGF1, TPM2_ALG_KDF1_SP800_56A,
1102 TPM2_ALG_KDF1_SP800_108, TPM2_ALG_NULL);
1103 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
1104 }
1105
1106 /** Serialize TPMI_ALG_SIG_SCHEME to json.
1107 *
1108 * @param[in] in variable to be serialized.
1109 * @param[out] jso pointer to the json object.
1110 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1111 * the function.
1112 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1113 */
1114 TSS2_RC
1115 ifapi_json_TPMI_ALG_SIG_SCHEME_serialize(const TPMI_ALG_SIG_SCHEME in,
1116 json_object **jso)
1117 {
1118 CHECK_IN_LIST(TPMI_ALG_SIG_SCHEME, in, TPM2_ALG_RSASSA, TPM2_ALG_RSAPSS,
1119 TPM2_ALG_ECDSA, TPM2_ALG_ECDAA, TPM2_ALG_SM2, TPM2_ALG_ECSCHNORR,
1120 TPM2_ALG_HMAC, TPM2_ALG_NULL);
1121 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
1122 }
1123
1124 /** Serialize a TPMU_HA to json.
1125 *
1126 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
1127 * @param[in] in the value to be serialized.
1128 * @param[in] selector the type of the HA object.
1129 * @param[out] jso pointer to the json object.
1130 * @retval TSS2_RC_SUCCESS if the function call was a success.
1131 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1132 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_HA.
1133 */
1134 TSS2_RC
1135 ifapi_json_TPMU_HA_serialize(const TPMU_HA *in, UINT32 selector,
1136 json_object **jso)
1137 {
1138 size_t size;
1139 const uint8_t *buffer;
1140
1141 switch (selector) {
1142 case TPM2_ALG_SHA1:
1143 size = TPM2_SHA1_DIGEST_SIZE;
1144 buffer = &in->sha1[0];
1145 break;
1146 case TPM2_ALG_SHA256:
1147 size = TPM2_SHA256_DIGEST_SIZE;
1148 buffer = &in->sha256[0];
1149 break;
1150 case TPM2_ALG_SHA384:
1151 size = TPM2_SHA384_DIGEST_SIZE;
1152 buffer = &in->sha384[0];
1153 break;
1154 case TPM2_ALG_SHA512:
1155 size = TPM2_SHA512_DIGEST_SIZE;
1156 buffer = &in->sha512[0];
1157 break;
1158 default:
1159 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
1160 return TSS2_FAPI_RC_BAD_VALUE;
1161 };
1162 char hex_string[(size) * 2 + 1];
1163 for (size_t i = 0, off = 0; i < size; i++, off += 2)
1164 sprintf(&hex_string[off], "%02x", buffer[i]);
1165 hex_string[(size) * 2] = '\0';
1166 *jso = json_object_new_string(hex_string);
1167 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1168
1169 return TSS2_RC_SUCCESS;
1170 }
1171
1172 /** Serialize value of type TPMT_HA to json.
1173 *
1174 * @param[in] in value to be serialized.
1175 * @param[out] jso pointer to the json object.
1176 * @retval TSS2_RC_SUCCESS if the function call was a success.
1177 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1178 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_HA.
1179 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1180 */
1181 TSS2_RC
1182 ifapi_json_TPMT_HA_serialize(const TPMT_HA *in, json_object **jso)
1183 {
1184 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1185
1186 TSS2_RC r;
1187 json_object *jso2;
1188 if (*jso == NULL)
1189 *jso = json_object_new_object();
1190 jso2 = NULL;
1191 r = ifapi_json_TPMI_ALG_HASH_serialize(in->hashAlg, &jso2);
1192 return_if_error(r, "Serialize TPMI_ALG_HASH");
1193
1194 json_object_object_add(*jso, "hashAlg", jso2);
1195 if (in->hashAlg != TPM2_ALG_NULL) {
1196 json_object *jso2 = NULL;
1197 r = ifapi_json_TPMU_HA_serialize(&in->digest, in->hashAlg, &jso2);
1198 return_if_error(r, "Serialize TPMU_HA");
1199
1200 json_object_object_add(*jso, "digest", jso2);
1201 }
1202 return TSS2_RC_SUCCESS;
1203 }
1204
1205 /** Serialize value of type TPM2B_DIGEST to json.
1206 *
1207 * @param[in] in value to be serialized.
1208 * @param[out] jso pointer to the json object.
1209 * @retval TSS2_RC_SUCCESS if the function call was a success.
1210 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1211 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_DIGEST.
1212 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1213 */
1214 TSS2_RC
1215 ifapi_json_TPM2B_DIGEST_serialize(const TPM2B_DIGEST *in, json_object **jso)
1216 {
1217 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1218
1219 if (in->size > sizeof(TPMU_HA)) {
1220 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = sizeof(TPMU_HA))",
1221 (size_t)in->size, (size_t)sizeof(TPMU_HA));
1222 return TSS2_FAPI_RC_BAD_VALUE;
1223 }
1224 char hex_string[((size_t)in->size)*2+1];
1225
1226 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
1227 sprintf(&hex_string[off], "%02x", in->buffer[i]);
1228 hex_string[(in->size)*2] = '\0';
1229 *jso = json_object_new_string (hex_string);
1230 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1231
1232 return TSS2_RC_SUCCESS;
1233 }
1234
1235 /** Serialize value of type TPM2B_DATA to json.
1236 *
1237 * @param[in] in value to be serialized.
1238 * @param[out] jso pointer to the json object.
1239 * @retval TSS2_RC_SUCCESS if the function call was a success.
1240 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1241 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_DATA.
1242 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1243 */
1244 TSS2_RC
1245 ifapi_json_TPM2B_DATA_serialize(const TPM2B_DATA *in, json_object **jso)
1246 {
1247 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1248
1249 if (in->size > sizeof(TPMT_HA)) {
1250 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = sizeof(TPMT_HA))",
1251 (size_t)in->size, (size_t)sizeof(TPMT_HA));
1252 return TSS2_FAPI_RC_BAD_VALUE;
1253 }
1254 char hex_string[sizeof(TPMT_HA)*2+1];
1255
1256 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
1257 sprintf(&hex_string[off], "%02x", in->buffer[i]);
1258 hex_string[(in->size)*2] = '\0';
1259 *jso = json_object_new_string (hex_string);
1260 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1261
1262 return TSS2_RC_SUCCESS;
1263 }
1264
1265 /** Serialize a TPM2B_NONCE to json.
1266 *
1267 * @param[in] in value of type TPM2B_NONCE to be serialized.
1268 * @param[out] jso pointer to the json object.
1269 * @retval TSS2_RC_SUCCESS if the function call was a success.
1270 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1271 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_NONCE.
1272 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1273 */
1274 TSS2_RC
1275 ifapi_json_TPM2B_NONCE_serialize(const TPM2B_NONCE *in, json_object **jso)
1276 {
1277 return ifapi_json_TPM2B_DIGEST_serialize(in, jso);
1278 }
1279
1280 /** Serialize a TPM2B_OPERAND to json.
1281 *
1282 * @param[in] in value of type TPM2B_OPERAND to be serialized.
1283 * @param[out] jso pointer to the json object.
1284 * @retval TSS2_RC_SUCCESS if the function call was a success.
1285 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1286 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_OPERAND.
1287 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1288 */
1289 TSS2_RC
1290 ifapi_json_TPM2B_OPERAND_serialize(const TPM2B_OPERAND *in, json_object **jso)
1291 {
1292 return ifapi_json_TPM2B_DIGEST_serialize(in, jso);
1293 }
1294
1295 /** Serialize value of type TPM2B_EVENT to json.
1296 *
1297 * @param[in] in value to be serialized.
1298 * @param[out] jso pointer to the json object.
1299 * @retval TSS2_RC_SUCCESS if the function call was a success.
1300 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1301 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_EVENT.
1302 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1303 */
1304 TSS2_RC
1305 ifapi_json_TPM2B_EVENT_serialize(const TPM2B_EVENT *in, json_object **jso)
1306 {
1307 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1308
1309 if (in->size > 1024) {
1310 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = 1024)",
1311 (size_t)in->size, (size_t)1024);
1312 return TSS2_FAPI_RC_BAD_VALUE;
1313 }
1314 char hex_string[((size_t)in->size)*2+1];
1315
1316 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
1317 sprintf(&hex_string[off], "%02x", in->buffer[i]);
1318 hex_string[(in->size)*2] = '\0';
1319 *jso = json_object_new_string (hex_string);
1320 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1321
1322 return TSS2_RC_SUCCESS;
1323 }
1324
1325 /** Serialize value of type TPM2B_MAX_NV_BUFFER to json.
1326 *
1327 * @param[in] in value to be serialized.
1328 * @param[out] jso pointer to the json object.
1329 * @retval TSS2_RC_SUCCESS if the function call was a success.
1330 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1331 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_MAX_NV_BUFFER.
1332 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1333 */
1334 TSS2_RC
1335 ifapi_json_TPM2B_MAX_NV_BUFFER_serialize(const TPM2B_MAX_NV_BUFFER *in, json_object **jso)
1336 {
1337 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1338
1339 if (in->size > TPM2_MAX_NV_BUFFER_SIZE) {
1340 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_NV_BUFFER_SIZE)",
1341 (size_t)in->size, (size_t)TPM2_MAX_NV_BUFFER_SIZE);
1342 return TSS2_FAPI_RC_BAD_VALUE;
1343 }
1344 char hex_string[((size_t)in->size)*2+1];
1345
1346 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
1347 sprintf(&hex_string[off], "%02x", in->buffer[i]);
1348 hex_string[(in->size)*2] = '\0';
1349 *jso = json_object_new_string (hex_string);
1350 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1351
1352 return TSS2_RC_SUCCESS;
1353 }
1354
1355 /** Serialize value of type TPM2B_NAME to json.
1356 *
1357 * @param[in] in value to be serialized.
1358 * @param[out] jso pointer to the json object.
1359 * @retval TSS2_RC_SUCCESS if the function call was a success.
1360 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1361 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_NAME.
1362 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1363 */
1364 TSS2_RC
1365 ifapi_json_TPM2B_NAME_serialize(const TPM2B_NAME *in, json_object **jso)
1366 {
1367 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1368
1369 if (in->size > sizeof(TPMU_NAME)) {
1370 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = sizeof(TPMU_NAME))",
1371 (size_t)in->size, (size_t)sizeof(TPMU_NAME));
1372 return TSS2_FAPI_RC_BAD_VALUE;
1373 }
1374 char hex_string[((size_t)in->size)*2+1];
1375
1376 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
1377 sprintf(&hex_string[off], "%02x", in->name[i]);
1378 hex_string[(in->size)*2] = '\0';
1379 *jso = json_object_new_string (hex_string);
1380 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1381
1382 return TSS2_RC_SUCCESS;
1383 }
1384
1385 /** Serialize value of type TPMT_TK_CREATION to json.
1386 *
1387 * @param[in] in value to be serialized.
1388 * @param[out] jso pointer to the json object.
1389 * @retval TSS2_RC_SUCCESS if the function call was a success.
1390 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1391 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_TK_CREATION.
1392 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1393 */
1394 TSS2_RC
1395 ifapi_json_TPMT_TK_CREATION_serialize(const TPMT_TK_CREATION *in, json_object **jso)
1396 {
1397 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1398
1399 TSS2_RC r;
1400 json_object *jso2;
1401 if (*jso == NULL)
1402 *jso = json_object_new_object ();
1403 if (in != NULL && in->tag != TPM2_ST_CREATION) {
1404 LOG_ERROR("BAD VALUE %"PRIuPTR" != %"PRIuPTR,(size_t)in->tag,(size_t)TPM2_ST_CREATION);
1405 return TSS2_FAPI_RC_BAD_VALUE;
1406 }
1407 jso2 = NULL;
1408 r = ifapi_json_TPM2_ST_serialize(in->tag, &jso2);
1409 return_if_error(r, "Serialize TPM2_ST");
1410
1411 json_object_object_add(*jso, "tag", jso2);
1412 jso2 = NULL;
1413 r = ifapi_json_TPMI_RH_HIERARCHY_serialize(in->hierarchy, &jso2);
1414 return_if_error(r, "Serialize TPMI_RH_HIERARCHY");
1415
1416 json_object_object_add(*jso, "hierarchy", jso2);
1417 jso2 = NULL;
1418 r = ifapi_json_TPM2B_DIGEST_serialize(&in->digest, &jso2);
1419 return_if_error(r, "Serialize TPM2B_DIGEST");
1420
1421 json_object_object_add(*jso, "digest", jso2);
1422 return TSS2_RC_SUCCESS;
1423 }
1424
1425 /** Serialize value of type TPMS_ALG_PROPERTY to json.
1426 *
1427 * @param[in] in value to be serialized.
1428 * @param[out] jso pointer to the json object.
1429 * @retval TSS2_RC_SUCCESS if the function call was a success.
1430 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1431 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_ALG_PROPERTY.
1432 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1433 */
1434 TSS2_RC
1435 ifapi_json_TPMS_ALG_PROPERTY_serialize(const TPMS_ALG_PROPERTY *in, json_object **jso)
1436 {
1437 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1438
1439 TSS2_RC r;
1440 json_object *jso2;
1441 if (*jso == NULL)
1442 *jso = json_object_new_object ();
1443 jso2 = NULL;
1444 r = ifapi_json_TPM2_ALG_ID_serialize(in->alg, &jso2);
1445 return_if_error(r, "Serialize TPM2_ALG_ID");
1446
1447 json_object_object_add(*jso, "alg", jso2);
1448 jso2 = NULL;
1449 r = ifapi_json_TPMA_ALGORITHM_serialize(in->algProperties, &jso2);
1450 return_if_error(r, "Serialize TPMA_ALGORITHM");
1451
1452 json_object_object_add(*jso, "algProperties", jso2);
1453 return TSS2_RC_SUCCESS;
1454 }
1455
1456 /** Serialize value of type TPMS_TAGGED_PROPERTY to json.
1457 *
1458 * @param[in] in value to be serialized.
1459 * @param[out] jso pointer to the json object.
1460 * @retval TSS2_RC_SUCCESS if the function call was a success.
1461 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1462 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_TAGGED_PROPERTY.
1463 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1464 */
1465 TSS2_RC
1466 ifapi_json_TPMS_TAGGED_PROPERTY_serialize(const TPMS_TAGGED_PROPERTY *in, json_object **jso)
1467 {
1468 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1469
1470 TSS2_RC r;
1471 json_object *jso2;
1472 if (*jso == NULL)
1473 *jso = json_object_new_object ();
1474 jso2 = NULL;
1475 r = ifapi_json_TPM2_PT_serialize(in->property, &jso2);
1476 return_if_error(r, "Serialize TPM2_PT");
1477
1478 json_object_object_add(*jso, "property", jso2);
1479 jso2 = NULL;
1480 r = ifapi_json_UINT32_serialize(in->value, &jso2);
1481 return_if_error(r, "Serialize UINT32");
1482
1483 json_object_object_add(*jso, "value", jso2);
1484 return TSS2_RC_SUCCESS;
1485 }
1486
1487 /** Serialize value of type TPML_CC to json.
1488 *
1489 * @param[in] in value to be serialized.
1490 * @param[out] jso pointer to the json object.
1491 * @retval TSS2_RC_SUCCESS if the function call was a success.
1492 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1493 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_CC.
1494 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1495 */
1496 TSS2_RC
1497 ifapi_json_TPML_CC_serialize(const TPML_CC *in, json_object **jso)
1498 {
1499 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1500
1501 TSS2_RC r;
1502 if (in->count > TPM2_MAX_CAP_CC) {
1503 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_CAP_CC)",
1504 (size_t)in->count, (size_t)TPM2_MAX_CAP_CC);
1505 return TSS2_FAPI_RC_BAD_VALUE;
1506 }
1507 *jso = json_object_new_array();
1508 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1509
1510 for (size_t i=0; i < in->count; i++) {
1511 json_object *jso2 = NULL;
1512 r = ifapi_json_TPM2_CC_serialize (in->commandCodes[i], &jso2);
1513 return_if_error(r, "Serialize TPM2_CC");
1514
1515 json_object_array_add(*jso, jso2);
1516 }
1517 return TSS2_RC_SUCCESS;
1518 }
1519
1520 /** Serialize value of type TPML_CCA to json.
1521 *
1522 * @param[in] in value to be serialized.
1523 * @param[out] jso pointer to the json object.
1524 * @retval TSS2_RC_SUCCESS if the function call was a success.
1525 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1526 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_CCA.
1527 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1528 */
1529 TSS2_RC
1530 ifapi_json_TPML_CCA_serialize(const TPML_CCA *in, json_object **jso)
1531 {
1532 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1533
1534 TSS2_RC r;
1535 if (in->count > TPM2_MAX_CAP_CC) {
1536 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_CAP_CC)",
1537 (size_t)in->count, (size_t)TPM2_MAX_CAP_CC);
1538 return TSS2_FAPI_RC_BAD_VALUE;
1539 }
1540 *jso = json_object_new_array();
1541 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1542
1543 for (size_t i=0; i < in->count; i++) {
1544 json_object *jso2 = NULL;
1545 r = ifapi_json_TPMA_CC_serialize (in->commandAttributes[i], &jso2);
1546 return_if_error(r, "Serialize TPMA_CC");
1547
1548 json_object_array_add(*jso, jso2);
1549 }
1550 return TSS2_RC_SUCCESS;
1551 }
1552
1553 /** Serialize value of type TPML_HANDLE to json.
1554 *
1555 * @param[in] in value to be serialized.
1556 * @param[out] jso pointer to the json object.
1557 * @retval TSS2_RC_SUCCESS if the function call was a success.
1558 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1559 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_HANDLE.
1560 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1561 */
1562 TSS2_RC
1563 ifapi_json_TPML_HANDLE_serialize(const TPML_HANDLE *in, json_object **jso)
1564 {
1565 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1566
1567 TSS2_RC r;
1568 if (in->count > TPM2_MAX_CAP_HANDLES) {
1569 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_CAP_HANDLES)",
1570 (size_t)in->count, (size_t)TPM2_MAX_CAP_HANDLES);
1571 return TSS2_FAPI_RC_BAD_VALUE;
1572 }
1573 *jso = json_object_new_array();
1574 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1575
1576 for (size_t i=0; i < in->count; i++) {
1577 json_object *jso2 = NULL;
1578 r = ifapi_json_TPM2_HANDLE_serialize (in->handle[i], &jso2);
1579 return_if_error(r, "Serialize TPM2_HANDLE");
1580
1581 json_object_array_add(*jso, jso2);
1582 }
1583 return TSS2_RC_SUCCESS;
1584 }
1585
1586 /** Serialize value of type TPML_DIGEST_VALUES to json.
1587 *
1588 * @param[in] in value to be serialized.
1589 * @param[out] jso pointer to the json object.
1590 * @retval TSS2_RC_SUCCESS if the function call was a success.
1591 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1592 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_DIGEST_VALUES.
1593 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1594 */
1595 TSS2_RC
1596 ifapi_json_TPML_DIGEST_VALUES_serialize(const TPML_DIGEST_VALUES *in, json_object **jso)
1597 {
1598 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1599
1600 TSS2_RC r;
1601 if (in->count > TPM2_NUM_PCR_BANKS) {
1602 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_NUM_PCR_BANKS)",
1603 (size_t)in->count, (size_t)TPM2_NUM_PCR_BANKS);
1604 return TSS2_FAPI_RC_BAD_VALUE;
1605 }
1606 *jso = json_object_new_array();
1607 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1608
1609 for (size_t i=0; i < in->count; i++) {
1610 json_object *jso2 = NULL;
1611 r = ifapi_json_TPMT_HA_serialize (&in->digests[i], &jso2);
1612 return_if_error(r, "Serialize TPMT_HA");
1613
1614 json_object_array_add(*jso, jso2);
1615 }
1616 return TSS2_RC_SUCCESS;
1617 }
1618
1619 /** Serialize value of type TPML_PCR_SELECTION to json.
1620 *
1621 * @param[in] in value to be serialized.
1622 * @param[out] jso pointer to the json object.
1623 * @retval TSS2_RC_SUCCESS if the function call was a success.
1624 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1625 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_PCR_SELECTION.
1626 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1627 */
1628 TSS2_RC
1629 ifapi_json_TPML_PCR_SELECTION_serialize(const TPML_PCR_SELECTION *in, json_object **jso)
1630 {
1631 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1632
1633 TSS2_RC r;
1634 if (in->count > TPM2_NUM_PCR_BANKS) {
1635 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_NUM_PCR_BANKS)",
1636 (size_t)in->count, (size_t)TPM2_NUM_PCR_BANKS);
1637 return TSS2_FAPI_RC_BAD_VALUE;
1638 }
1639 *jso = json_object_new_array();
1640 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1641
1642 for (size_t i=0; i < in->count; i++) {
1643 json_object *jso2 = NULL;
1644 r = ifapi_json_TPMS_PCR_SELECTION_serialize (&in->pcrSelections[i], &jso2);
1645 return_if_error(r, "Serialize TPMS_PCR_SELECTION");
1646
1647 json_object_array_add(*jso, jso2);
1648 }
1649 return TSS2_RC_SUCCESS;
1650 }
1651
1652 /** Serialize value of type TPML_ALG_PROPERTY to json.
1653 *
1654 * @param[in] in value to be serialized.
1655 * @param[out] jso pointer to the json object.
1656 * @retval TSS2_RC_SUCCESS if the function call was a success.
1657 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1658 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_ALG_PROPERTY.
1659 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1660 */
1661 TSS2_RC
1662 ifapi_json_TPML_ALG_PROPERTY_serialize(const TPML_ALG_PROPERTY *in, json_object **jso)
1663 {
1664 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1665
1666 TSS2_RC r;
1667 if (in->count > TPM2_MAX_CAP_ALGS) {
1668 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_CAP_ALGS)",
1669 (size_t)in->count, (size_t)TPM2_MAX_CAP_ALGS);
1670 return TSS2_FAPI_RC_BAD_VALUE;
1671 }
1672 *jso = json_object_new_array();
1673 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1674
1675 for (size_t i=0; i < in->count; i++) {
1676 json_object *jso2 = NULL;
1677 r = ifapi_json_TPMS_ALG_PROPERTY_serialize (&in->algProperties[i], &jso2);
1678 return_if_error(r, "Serialize TPMS_ALG_PROPERTY");
1679
1680 json_object_array_add(*jso, jso2);
1681 }
1682 return TSS2_RC_SUCCESS;
1683 }
1684
1685 /** Serialize value of type TPML_TAGGED_TPM_PROPERTY to json.
1686 *
1687 * @param[in] in value to be serialized.
1688 * @param[out] jso pointer to the json object.
1689 * @retval TSS2_RC_SUCCESS if the function call was a success.
1690 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1691 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_TAGGED_TPM_PROPERTY.
1692 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1693 */
1694 TSS2_RC
1695 ifapi_json_TPML_TAGGED_TPM_PROPERTY_serialize(const TPML_TAGGED_TPM_PROPERTY *in, json_object **jso)
1696 {
1697 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1698
1699 TSS2_RC r;
1700 if (in->count > TPM2_MAX_TPM_PROPERTIES) {
1701 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_TPM_PROPERTIES)",
1702 (size_t)in->count, (size_t)TPM2_MAX_TPM_PROPERTIES);
1703 return TSS2_FAPI_RC_BAD_VALUE;
1704 }
1705 *jso = json_object_new_array();
1706 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1707
1708 for (size_t i=0; i < in->count; i++) {
1709 json_object *jso2 = NULL;
1710 r = ifapi_json_TPMS_TAGGED_PROPERTY_serialize (&in->tpmProperty[i], &jso2);
1711 return_if_error(r, "Serialize TPMS_TAGGED_PROPERTY");
1712
1713 json_object_array_add(*jso, jso2);
1714 }
1715 return TSS2_RC_SUCCESS;
1716 }
1717
1718 /** Serialize value of type TPML_TAGGED_PCR_PROPERTY to json.
1719 *
1720 * @param[in] in value to be serialized.
1721 * @param[out] jso pointer to the json object.
1722 * @retval TSS2_RC_SUCCESS if the function call was a success.
1723 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1724 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_TAGGED_PCR_PROPERTY.
1725 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1726 */
1727 TSS2_RC
1728 ifapi_json_TPML_TAGGED_PCR_PROPERTY_serialize(const TPML_TAGGED_PCR_PROPERTY *in, json_object **jso)
1729 {
1730 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1731
1732 TSS2_RC r;
1733 if (in->count > TPM2_MAX_PCR_PROPERTIES) {
1734 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_PCR_PROPERTIES)",
1735 (size_t)in->count, (size_t)TPM2_MAX_PCR_PROPERTIES);
1736 return TSS2_FAPI_RC_BAD_VALUE;
1737 }
1738 *jso = json_object_new_array();
1739 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1740
1741 for (size_t i=0; i < in->count; i++) {
1742 json_object *jso2 = NULL;
1743 r = ifapi_json_TPMS_TAGGED_PCR_SELECT_serialize (&in->pcrProperty[i], &jso2);
1744 return_if_error(r, "Serialize TPMS_TAGGED_PCR_SELECT");
1745
1746 json_object_array_add(*jso, jso2);
1747 }
1748 return TSS2_RC_SUCCESS;
1749 }
1750
1751 /** Serialize value of type TPML_ECC_CURVE to json.
1752 *
1753 * @param[in] in value to be serialized.
1754 * @param[out] jso pointer to the json object.
1755 * @retval TSS2_RC_SUCCESS if the function call was a success.
1756 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1757 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPML_ECC_CURVE.
1758 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1759 */
1760 TSS2_RC
1761 ifapi_json_TPML_ECC_CURVE_serialize(const TPML_ECC_CURVE *in, json_object **jso)
1762 {
1763 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1764
1765 TSS2_RC r;
1766 if (in->count > TPM2_MAX_ECC_CURVES) {
1767 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_ECC_CURVES)",
1768 (size_t)in->count, (size_t)TPM2_MAX_ECC_CURVES);
1769 return TSS2_FAPI_RC_BAD_VALUE;
1770 }
1771 *jso = json_object_new_array();
1772 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
1773
1774 for (size_t i=0; i < in->count; i++) {
1775 json_object *jso2 = NULL;
1776 r = ifapi_json_TPM2_ECC_CURVE_serialize (in->eccCurves[i], &jso2);
1777 return_if_error(r, "Serialize TPM2_ECC_CURVE");
1778
1779 json_object_array_add(*jso, jso2);
1780 }
1781 return TSS2_RC_SUCCESS;
1782 }
1783
1784 /** Serialize a TPMU_CAPABILITIES to json.
1785 *
1786 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
1787 * @param[in] in the value to be serialized.
1788 * @param[in] selector the type of the capabilities.
1789 * @param[out] jso pointer to the json object.
1790 * @retval TSS2_RC_SUCCESS if the function call was a success.
1791 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1792 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_CAPABILITIES.
1793 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1794 */
1795 TSS2_RC
1796 ifapi_json_TPMU_CAPABILITIES_serialize(const TPMU_CAPABILITIES *in, UINT32 selector, json_object **jso)
1797 {
1798 switch (selector) {
1799 case TPM2_CAP_ALGS:
1800 return ifapi_json_TPML_ALG_PROPERTY_serialize(&in->algorithms, jso);
1801 case TPM2_CAP_HANDLES:
1802 return ifapi_json_TPML_HANDLE_serialize(&in->handles, jso);
1803 case TPM2_CAP_COMMANDS:
1804 return ifapi_json_TPML_CCA_serialize(&in->command, jso);
1805 case TPM2_CAP_PP_COMMANDS:
1806 return ifapi_json_TPML_CC_serialize(&in->ppCommands, jso);
1807 case TPM2_CAP_AUDIT_COMMANDS:
1808 return ifapi_json_TPML_CC_serialize(&in->auditCommands, jso);
1809 case TPM2_CAP_PCRS:
1810 return ifapi_json_TPML_PCR_SELECTION_serialize(&in->assignedPCR, jso);
1811 case TPM2_CAP_TPM_PROPERTIES:
1812 return ifapi_json_TPML_TAGGED_TPM_PROPERTY_serialize(&in->tpmProperties, jso);
1813 case TPM2_CAP_PCR_PROPERTIES:
1814 return ifapi_json_TPML_TAGGED_PCR_PROPERTY_serialize(&in->pcrProperties, jso);
1815 case TPM2_CAP_ECC_CURVES:
1816 return ifapi_json_TPML_ECC_CURVE_serialize(&in->eccCurves, jso);
1817 default:
1818 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
1819 return TSS2_FAPI_RC_BAD_VALUE;
1820 };
1821 return TSS2_RC_SUCCESS;
1822 }
1823
1824 /** Serialize value of type TPMS_CAPABILITY_DATA to json.
1825 *
1826 * @param[in] in value to be serialized.
1827 * @param[out] jso pointer to the json object.
1828 * @retval TSS2_RC_SUCCESS if the function call was a success.
1829 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1830 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_CAPABILITY_DATA.
1831 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1832 */
1833 TSS2_RC
1834 ifapi_json_TPMS_CAPABILITY_DATA_serialize(const TPMS_CAPABILITY_DATA *in, json_object **jso)
1835 {
1836 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1837
1838 TSS2_RC r;
1839 json_object *jso2;
1840 if (*jso == NULL)
1841 *jso = json_object_new_object ();
1842 jso2 = NULL;
1843 r = ifapi_json_TPM2_CAP_serialize(in->capability, &jso2);
1844 return_if_error(r, "Serialize TPM2_CAP");
1845
1846 json_object_object_add(*jso, "capability", jso2);
1847 jso2 = NULL;
1848 r = ifapi_json_TPMU_CAPABILITIES_serialize(&in->data, in->capability, &jso2);
1849 return_if_error(r,"Serialize TPMU_CAPABILITIES");
1850
1851 json_object_object_add(*jso, "data", jso2);
1852 return TSS2_RC_SUCCESS;
1853 }
1854
1855 /** Serialize value of type TPMS_CLOCK_INFO to json.
1856 *
1857 * @param[in] in value to be serialized.
1858 * @param[out] jso pointer to the json object.
1859 * @retval TSS2_RC_SUCCESS if the function call was a success.
1860 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1861 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_CLOCK_INFO.
1862 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1863 */
1864 TSS2_RC
1865 ifapi_json_TPMS_CLOCK_INFO_serialize(const TPMS_CLOCK_INFO *in, json_object **jso)
1866 {
1867 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1868
1869 TSS2_RC r;
1870 json_object *jso2;
1871 if (*jso == NULL)
1872 *jso = json_object_new_object ();
1873 jso2 = NULL;
1874 r = ifapi_json_UINT64_serialize(in->clock, &jso2);
1875 return_if_error(r, "Serialize UINT64");
1876
1877 json_object_object_add(*jso, "clock", jso2);
1878 jso2 = NULL;
1879 r = ifapi_json_UINT32_serialize(in->resetCount, &jso2);
1880 return_if_error(r, "Serialize UINT32");
1881
1882 json_object_object_add(*jso, "resetCount", jso2);
1883 jso2 = NULL;
1884 r = ifapi_json_UINT32_serialize(in->restartCount, &jso2);
1885 return_if_error(r, "Serialize UINT32");
1886
1887 json_object_object_add(*jso, "restartCount", jso2);
1888 jso2 = NULL;
1889 r = ifapi_json_TPMI_YES_NO_serialize(in->safe, &jso2);
1890 return_if_error(r, "Serialize TPMI_YES_NO");
1891
1892 json_object_object_add(*jso, "safe", jso2);
1893 return TSS2_RC_SUCCESS;
1894 }
1895
1896 /** Serialize value of type TPMS_TIME_INFO to json.
1897 *
1898 * @param[in] in value to be serialized.
1899 * @param[out] jso pointer to the json object.
1900 * @retval TSS2_RC_SUCCESS if the function call was a success.
1901 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1902 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_TIME_INFO.
1903 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1904 */
1905 TSS2_RC
1906 ifapi_json_TPMS_TIME_INFO_serialize(const TPMS_TIME_INFO *in, json_object **jso)
1907 {
1908 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1909
1910 TSS2_RC r;
1911 json_object *jso2;
1912 if (*jso == NULL)
1913 *jso = json_object_new_object ();
1914 jso2 = NULL;
1915 r = ifapi_json_UINT64_serialize(in->time, &jso2);
1916 return_if_error(r, "Serialize UINT64");
1917
1918 json_object_object_add(*jso, "time", jso2);
1919 jso2 = NULL;
1920 r = ifapi_json_TPMS_CLOCK_INFO_serialize(&in->clockInfo, &jso2);
1921 return_if_error(r, "Serialize TPMS_CLOCK_INFO");
1922
1923 json_object_object_add(*jso, "clockInfo", jso2);
1924 return TSS2_RC_SUCCESS;
1925 }
1926
1927 /** Serialize value of type TPMS_TIME_ATTEST_INFO to json.
1928 *
1929 * @param[in] in value to be serialized.
1930 * @param[out] jso pointer to the json object.
1931 * @retval TSS2_RC_SUCCESS if the function call was a success.
1932 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1933 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_TIME_ATTEST_INFO.
1934 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1935 */
1936 TSS2_RC
1937 ifapi_json_TPMS_TIME_ATTEST_INFO_serialize(const TPMS_TIME_ATTEST_INFO *in, json_object **jso)
1938 {
1939 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1940
1941 TSS2_RC r;
1942 json_object *jso2;
1943 if (*jso == NULL)
1944 *jso = json_object_new_object ();
1945 jso2 = NULL;
1946 r = ifapi_json_TPMS_TIME_INFO_serialize(&in->time, &jso2);
1947 return_if_error(r, "Serialize TPMS_TIME_INFO");
1948
1949 json_object_object_add(*jso, "time", jso2);
1950 jso2 = NULL;
1951 r = ifapi_json_UINT64_serialize(in->firmwareVersion, &jso2);
1952 return_if_error(r, "Serialize UINT64");
1953
1954 json_object_object_add(*jso, "firmwareVersion", jso2);
1955 return TSS2_RC_SUCCESS;
1956 }
1957
1958 /** Serialize value of type TPMS_CERTIFY_INFO to json.
1959 *
1960 * @param[in] in value to be serialized.
1961 * @param[out] jso pointer to the json object.
1962 * @retval TSS2_RC_SUCCESS if the function call was a success.
1963 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1964 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_CERTIFY_INFO.
1965 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1966 */
1967 TSS2_RC
1968 ifapi_json_TPMS_CERTIFY_INFO_serialize(const TPMS_CERTIFY_INFO *in, json_object **jso)
1969 {
1970 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
1971
1972 TSS2_RC r;
1973 json_object *jso2;
1974 if (*jso == NULL)
1975 *jso = json_object_new_object ();
1976 jso2 = NULL;
1977 r = ifapi_json_TPM2B_NAME_serialize(&in->name, &jso2);
1978 return_if_error(r, "Serialize TPM2B_NAME");
1979
1980 json_object_object_add(*jso, "name", jso2);
1981 jso2 = NULL;
1982 r = ifapi_json_TPM2B_NAME_serialize(&in->qualifiedName, &jso2);
1983 return_if_error(r, "Serialize TPM2B_NAME");
1984
1985 json_object_object_add(*jso, "qualifiedName", jso2);
1986 return TSS2_RC_SUCCESS;
1987 }
1988
1989 /** Serialize value of type TPMS_QUOTE_INFO to json.
1990 *
1991 * @param[in] in value to be serialized.
1992 * @param[out] jso pointer to the json object.
1993 * @retval TSS2_RC_SUCCESS if the function call was a success.
1994 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
1995 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_QUOTE_INFO.
1996 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1997 */
1998 TSS2_RC
1999 ifapi_json_TPMS_QUOTE_INFO_serialize(const TPMS_QUOTE_INFO *in, json_object **jso)
2000 {
2001 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2002
2003 TSS2_RC r;
2004 json_object *jso2;
2005 if (*jso == NULL)
2006 *jso = json_object_new_object ();
2007 jso2 = NULL;
2008 r = ifapi_json_TPML_PCR_SELECTION_serialize(&in->pcrSelect, &jso2);
2009 return_if_error(r, "Serialize TPML_PCR_SELECTION");
2010
2011 json_object_object_add(*jso, "pcrSelect", jso2);
2012 jso2 = NULL;
2013 r = ifapi_json_TPM2B_DIGEST_serialize(&in->pcrDigest, &jso2);
2014 return_if_error(r, "Serialize TPM2B_DIGEST");
2015
2016 json_object_object_add(*jso, "pcrDigest", jso2);
2017 return TSS2_RC_SUCCESS;
2018 }
2019
2020 /** Serialize value of type TPMS_COMMAND_AUDIT_INFO to json.
2021 *
2022 * @param[in] in value to be serialized.
2023 * @param[out] jso pointer to the json object.
2024 * @retval TSS2_RC_SUCCESS if the function call was a success.
2025 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2026 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_COMMAND_AUDIT_INFO.
2027 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2028 */
2029 TSS2_RC
2030 ifapi_json_TPMS_COMMAND_AUDIT_INFO_serialize(const TPMS_COMMAND_AUDIT_INFO *in, json_object **jso)
2031 {
2032 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2033
2034 TSS2_RC r;
2035 json_object *jso2;
2036 if (*jso == NULL)
2037 *jso = json_object_new_object ();
2038 jso2 = NULL;
2039 r = ifapi_json_UINT64_serialize(in->auditCounter, &jso2);
2040 return_if_error(r, "Serialize UINT64");
2041
2042 json_object_object_add(*jso, "auditCounter", jso2);
2043 jso2 = NULL;
2044 r = ifapi_json_TPM2_ALG_ID_serialize(in->digestAlg, &jso2);
2045 return_if_error(r, "Serialize TPM2_ALG_ID");
2046
2047 json_object_object_add(*jso, "digestAlg", jso2);
2048 jso2 = NULL;
2049 r = ifapi_json_TPM2B_DIGEST_serialize(&in->auditDigest, &jso2);
2050 return_if_error(r, "Serialize TPM2B_DIGEST");
2051
2052 json_object_object_add(*jso, "auditDigest", jso2);
2053 jso2 = NULL;
2054 r = ifapi_json_TPM2B_DIGEST_serialize(&in->commandDigest, &jso2);
2055 return_if_error(r, "Serialize TPM2B_DIGEST");
2056
2057 json_object_object_add(*jso, "commandDigest", jso2);
2058 return TSS2_RC_SUCCESS;
2059 }
2060
2061 /** Serialize value of type TPMS_SESSION_AUDIT_INFO to json.
2062 *
2063 * @param[in] in value to be serialized.
2064 * @param[out] jso pointer to the json object.
2065 * @retval TSS2_RC_SUCCESS if the function call was a success.
2066 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2067 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SESSION_AUDIT_INFO.
2068 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2069 */
2070 TSS2_RC
2071 ifapi_json_TPMS_SESSION_AUDIT_INFO_serialize(const TPMS_SESSION_AUDIT_INFO *in, json_object **jso)
2072 {
2073 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2074
2075 TSS2_RC r;
2076 json_object *jso2;
2077 if (*jso == NULL)
2078 *jso = json_object_new_object ();
2079 jso2 = NULL;
2080 r = ifapi_json_TPMI_YES_NO_serialize(in->exclusiveSession, &jso2);
2081 return_if_error(r, "Serialize TPMI_YES_NO");
2082
2083 json_object_object_add(*jso, "exclusiveSession", jso2);
2084 jso2 = NULL;
2085 r = ifapi_json_TPM2B_DIGEST_serialize(&in->sessionDigest, &jso2);
2086 return_if_error(r, "Serialize TPM2B_DIGEST");
2087
2088 json_object_object_add(*jso, "sessionDigest", jso2);
2089 return TSS2_RC_SUCCESS;
2090 }
2091
2092 /** Serialize value of type TPMS_CREATION_INFO to json.
2093 *
2094 * @param[in] in value to be serialized.
2095 * @param[out] jso pointer to the json object.
2096 * @retval TSS2_RC_SUCCESS if the function call was a success.
2097 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2098 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_CREATION_INFO.
2099 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2100 */
2101 TSS2_RC
2102 ifapi_json_TPMS_CREATION_INFO_serialize(const TPMS_CREATION_INFO *in, json_object **jso)
2103 {
2104 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2105
2106 TSS2_RC r;
2107 json_object *jso2;
2108 if (*jso == NULL)
2109 *jso = json_object_new_object ();
2110 jso2 = NULL;
2111 r = ifapi_json_TPM2B_NAME_serialize(&in->objectName, &jso2);
2112 return_if_error(r, "Serialize TPM2B_NAME");
2113
2114 json_object_object_add(*jso, "objectName", jso2);
2115 jso2 = NULL;
2116 r = ifapi_json_TPM2B_DIGEST_serialize(&in->creationHash, &jso2);
2117 return_if_error(r, "Serialize TPM2B_DIGEST");
2118
2119 json_object_object_add(*jso, "creationHash", jso2);
2120 return TSS2_RC_SUCCESS;
2121 }
2122
2123 /** Serialize value of type TPMS_NV_CERTIFY_INFO to json.
2124 *
2125 * @param[in] in value to be serialized.
2126 * @param[out] jso pointer to the json object.
2127 * @retval TSS2_RC_SUCCESS if the function call was a success.
2128 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2129 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_NV_CERTIFY_INFO.
2130 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2131 */
2132 TSS2_RC
2133 ifapi_json_TPMS_NV_CERTIFY_INFO_serialize(const TPMS_NV_CERTIFY_INFO *in, json_object **jso)
2134 {
2135 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2136
2137 TSS2_RC r;
2138 json_object *jso2;
2139 if (*jso == NULL)
2140 *jso = json_object_new_object ();
2141 jso2 = NULL;
2142 r = ifapi_json_TPM2B_NAME_serialize(&in->indexName, &jso2);
2143 return_if_error(r, "Serialize TPM2B_NAME");
2144
2145 json_object_object_add(*jso, "indexName", jso2);
2146 jso2 = NULL;
2147 r = ifapi_json_UINT16_serialize(in->offset, &jso2);
2148 return_if_error(r, "Serialize UINT16");
2149
2150 json_object_object_add(*jso, "offset", jso2);
2151 jso2 = NULL;
2152 r = ifapi_json_TPM2B_MAX_NV_BUFFER_serialize(&in->nvContents, &jso2);
2153 return_if_error(r, "Serialize TPM2B_MAX_NV_BUFFER");
2154
2155 json_object_object_add(*jso, "nvContents", jso2);
2156 return TSS2_RC_SUCCESS;
2157 }
2158
2159 /** Serialize TPMI_ST_ATTEST to json.
2160 *
2161 * @param[in] in variable to be serialized.
2162 * @param[out] jso pointer to the json object.
2163 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2164 * the function.
2165 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2166 */
2167 TSS2_RC
2168 ifapi_json_TPMI_ST_ATTEST_serialize(const TPMI_ST_ATTEST in, json_object **jso)
2169 {
2170 CHECK_IN_LIST(TPMI_ALG_HASH, in, TPM2_ST_ATTEST_CERTIFY, TPM2_ST_ATTEST_QUOTE,
2171 TPM2_ST_ATTEST_SESSION_AUDIT, TPM2_ST_ATTEST_COMMAND_AUDIT,
2172 TPM2_ST_ATTEST_TIME, TPM2_ST_ATTEST_CREATION, TPM2_ST_ATTEST_NV);
2173 return ifapi_json_TPM2_ST_serialize(in, jso);
2174 }
2175
2176 /** Serialize a TPMU_ATTEST to json.
2177 *
2178 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
2179 * @param[in] in the value to be serialized.
2180 * @param[in] selector the type of the attest.
2181 * @param[out] jso pointer to the json object.
2182 * @retval TSS2_RC_SUCCESS if the function call was a success.
2183 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2184 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_ATTEST.
2185 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2186 */
2187 TSS2_RC
2188 ifapi_json_TPMU_ATTEST_serialize(const TPMU_ATTEST *in, UINT32 selector, json_object **jso)
2189 {
2190 switch (selector) {
2191 case TPM2_ST_ATTEST_CERTIFY:
2192 return ifapi_json_TPMS_CERTIFY_INFO_serialize(&in->certify, jso);
2193 case TPM2_ST_ATTEST_CREATION:
2194 return ifapi_json_TPMS_CREATION_INFO_serialize(&in->creation, jso);
2195 case TPM2_ST_ATTEST_QUOTE:
2196 return ifapi_json_TPMS_QUOTE_INFO_serialize(&in->quote, jso);
2197 case TPM2_ST_ATTEST_COMMAND_AUDIT:
2198 return ifapi_json_TPMS_COMMAND_AUDIT_INFO_serialize(&in->commandAudit, jso);
2199 case TPM2_ST_ATTEST_SESSION_AUDIT:
2200 return ifapi_json_TPMS_SESSION_AUDIT_INFO_serialize(&in->sessionAudit, jso);
2201 case TPM2_ST_ATTEST_TIME:
2202 return ifapi_json_TPMS_TIME_ATTEST_INFO_serialize(&in->time, jso);
2203 case TPM2_ST_ATTEST_NV:
2204 return ifapi_json_TPMS_NV_CERTIFY_INFO_serialize(&in->nv, jso);
2205 default:
2206 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
2207 return TSS2_FAPI_RC_BAD_VALUE;
2208 };
2209 return TSS2_RC_SUCCESS;
2210 }
2211
2212 /** Serialize value of type TPMS_ATTEST to json.
2213 *
2214 * @param[in] in value to be serialized.
2215 * @param[out] jso pointer to the json object.
2216 * @retval TSS2_RC_SUCCESS if the function call was a success.
2217 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2218 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_ATTEST.
2219 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2220 */
2221 TSS2_RC
2222 ifapi_json_TPMS_ATTEST_serialize(const TPMS_ATTEST *in, json_object **jso)
2223 {
2224 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2225
2226 TSS2_RC r;
2227 json_object *jso2;
2228 if (*jso == NULL)
2229 *jso = json_object_new_object ();
2230 jso2 = NULL;
2231 r = ifapi_json_TPM2_GENERATED_serialize(in->magic, &jso2);
2232 return_if_error(r, "Serialize TPM2_GENERATED");
2233
2234 json_object_object_add(*jso, "magic", jso2);
2235 jso2 = NULL;
2236 r = ifapi_json_TPMI_ST_ATTEST_serialize(in->type, &jso2);
2237 return_if_error(r, "Serialize TPMI_ST_ATTEST");
2238
2239 json_object_object_add(*jso, "type", jso2);
2240 jso2 = NULL;
2241 r = ifapi_json_TPM2B_NAME_serialize(&in->qualifiedSigner, &jso2);
2242 return_if_error(r, "Serialize TPM2B_NAME");
2243
2244 json_object_object_add(*jso, "qualifiedSigner", jso2);
2245 jso2 = NULL;
2246 r = ifapi_json_TPM2B_DATA_serialize(&in->extraData, &jso2);
2247 return_if_error(r, "Serialize TPM2B_DATA");
2248
2249 json_object_object_add(*jso, "extraData", jso2);
2250 jso2 = NULL;
2251 r = ifapi_json_TPMS_CLOCK_INFO_serialize(&in->clockInfo, &jso2);
2252 return_if_error(r, "Serialize TPMS_CLOCK_INFO");
2253
2254 json_object_object_add(*jso, "clockInfo", jso2);
2255 jso2 = NULL;
2256 r = ifapi_json_UINT64_serialize(in->firmwareVersion, &jso2);
2257 return_if_error(r, "Serialize UINT64");
2258
2259 json_object_object_add(*jso, "firmwareVersion", jso2);
2260 jso2 = NULL;
2261 r = ifapi_json_TPMU_ATTEST_serialize(&in->attested, in->type, &jso2);
2262 return_if_error(r,"Serialize TPMU_ATTEST");
2263
2264 json_object_object_add(*jso, "attested", jso2);
2265 return TSS2_RC_SUCCESS;
2266 }
2267
2268 /** Serialize value of type TPMI_AES_KEY_BITS to json.
2269 *
2270 * @param[in] in value to be serialized.
2271 * @param[out] jso pointer to the json object.
2272 * @retval TSS2_RC_SUCCESS if the function call was a success.
2273 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2274 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMI_AES_KEY_BITS.
2275 *
2276 */
2277 TSS2_RC
2278 ifapi_json_TPMI_AES_KEY_BITS_serialize(const TPMI_AES_KEY_BITS in, json_object **jso)
2279 {
2280 CHECK_IN_LIST(UINT16, in, 128, 192, 256);
2281 return ifapi_json_UINT16_serialize(in, jso);
2282 }
2283
2284 /** Serialize a TPMU_SYM_KEY_BITS to json.
2285 *
2286 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
2287 * @param[in] in the value to be serialized.
2288 * @param[in] selector the type of the symmetric algorithm.
2289 * @param[out] jso pointer to the json object.
2290 * @retval TSS2_RC_SUCCESS if the function call was a success.
2291 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2292 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_SYM_KEY_BITS.
2293 */
2294 TSS2_RC
2295 ifapi_json_TPMU_SYM_KEY_BITS_serialize(const TPMU_SYM_KEY_BITS *in, UINT32 selector, json_object **jso)
2296 {
2297 switch (selector) {
2298 case TPM2_ALG_AES:
2299 return ifapi_json_TPMI_AES_KEY_BITS_serialize(in->aes, jso);
2300 case TPM2_ALG_XOR:
2301 return ifapi_json_TPMI_ALG_HASH_serialize(in->exclusiveOr, jso);
2302 default:
2303 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
2304 return TSS2_FAPI_RC_BAD_VALUE;
2305 };
2306 return TSS2_RC_SUCCESS;
2307 }
2308
2309 /** Serialize a TPMU_SYM_MODE to json.
2310 *
2311 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
2312 * @param[in] in the value to be serialized.
2313 * @param[in] selector the type of the symmetric mode.
2314 * @param[out] jso pointer to the json object.
2315 * @retval TSS2_RC_SUCCESS if the function call was a success.
2316 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2317 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_SYM_MODE.
2318 */
2319 TSS2_RC
2320 ifapi_json_TPMU_SYM_MODE_serialize(const TPMU_SYM_MODE *in, UINT32 selector, json_object **jso)
2321 {
2322 switch (selector) {
2323 case TPM2_ALG_AES:
2324 return ifapi_json_TPMI_ALG_SYM_MODE_serialize(in->aes, jso);
2325 default:
2326 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
2327 return TSS2_FAPI_RC_BAD_VALUE;
2328 };
2329 return TSS2_RC_SUCCESS;
2330 }
2331
2332 /** Serialize value of type TPMT_SYM_DEF_OBJECT to json.
2333 *
2334 * @param[in] in value to be serialized.
2335 * @param[out] jso pointer to the json object.
2336 * @retval TSS2_RC_SUCCESS if the function call was a success.
2337 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2338 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_SYM_DEF_OBJECT.
2339 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2340 */
2341 TSS2_RC
2342 ifapi_json_TPMT_SYM_DEF_OBJECT_serialize(const TPMT_SYM_DEF_OBJECT *in, json_object **jso)
2343 {
2344 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2345
2346 TSS2_RC r;
2347 json_object *jso2;
2348 if (*jso == NULL)
2349 *jso = json_object_new_object ();
2350 jso2 = NULL;
2351 r = ifapi_json_TPMI_ALG_SYM_OBJECT_serialize(in->algorithm, &jso2);
2352 return_if_error(r, "Serialize TPMI_ALG_SYM_OBJECT");
2353
2354 json_object_object_add(*jso, "algorithm", jso2);
2355 if (in->algorithm != TPM2_ALG_NULL) {
2356 json_object *jso2 = NULL;
2357 r = ifapi_json_TPMU_SYM_KEY_BITS_serialize(&in->keyBits, in->algorithm, &jso2);
2358 return_if_error(r,"Serialize TPMU_SYM_KEY_BITS");
2359
2360 json_object_object_add(*jso, "keyBits", jso2);
2361 }
2362 if (in->algorithm != TPM2_ALG_NULL) {
2363 json_object *jso2 = NULL;
2364 r = ifapi_json_TPMU_SYM_MODE_serialize(&in->mode, in->algorithm, &jso2);
2365 return_if_error(r,"Serialize TPMU_SYM_MODE");
2366
2367 json_object_object_add(*jso, "mode", jso2);
2368 }
2369 return TSS2_RC_SUCCESS;
2370 }
2371
2372 /** Serialize value of type TPMS_SYMCIPHER_PARMS to json.
2373 *
2374 * @param[in] in value to be serialized.
2375 * @param[out] jso pointer to the json object.
2376 * @retval TSS2_RC_SUCCESS if the function call was a success.
2377 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2378 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SYMCIPHER_PARMS.
2379 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2380 */
2381 TSS2_RC
2382 ifapi_json_TPMS_SYMCIPHER_PARMS_serialize(const TPMS_SYMCIPHER_PARMS *in, json_object **jso)
2383 {
2384 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2385
2386 TSS2_RC r;
2387 json_object *jso2;
2388 if (*jso == NULL)
2389 *jso = json_object_new_object ();
2390 jso2 = NULL;
2391 r = ifapi_json_TPMT_SYM_DEF_OBJECT_serialize(&in->sym, &jso2);
2392 return_if_error(r, "Serialize TPMT_SYM_DEF_OBJECT");
2393
2394 json_object_object_add(*jso, "sym", jso2);
2395 return TSS2_RC_SUCCESS;
2396 }
2397
2398 /** Serialize value of type TPMS_SCHEME_HASH to json.
2399 *
2400 * @param[in] in value to be serialized.
2401 * @param[out] jso pointer to the json object.
2402 * @retval TSS2_RC_SUCCESS if the function call was a success.
2403 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2404 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SCHEME_HASH.
2405 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2406 */
2407 TSS2_RC
2408 ifapi_json_TPMS_SCHEME_HASH_serialize(const TPMS_SCHEME_HASH *in, json_object **jso)
2409 {
2410 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2411
2412 TSS2_RC r;
2413 json_object *jso2;
2414 if (*jso == NULL)
2415 *jso = json_object_new_object ();
2416 jso2 = NULL;
2417 r = ifapi_json_TPMI_ALG_HASH_serialize(in->hashAlg, &jso2);
2418 return_if_error(r, "Serialize TPMI_ALG_HASH");
2419
2420 json_object_object_add(*jso, "hashAlg", jso2);
2421 return TSS2_RC_SUCCESS;
2422 }
2423
2424 /** Serialize value of type TPMS_SCHEME_ECDAA to json.
2425 *
2426 * @param[in] in value to be serialized.
2427 * @param[out] jso pointer to the json object.
2428 * @retval TSS2_RC_SUCCESS if the function call was a success.
2429 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2430 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SCHEME_ECDAA.
2431 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2432 */
2433 TSS2_RC
2434 ifapi_json_TPMS_SCHEME_ECDAA_serialize(const TPMS_SCHEME_ECDAA *in, json_object **jso)
2435 {
2436 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2437
2438 TSS2_RC r;
2439 json_object *jso2;
2440 if (*jso == NULL)
2441 *jso = json_object_new_object ();
2442 jso2 = NULL;
2443 r = ifapi_json_TPMI_ALG_HASH_serialize(in->hashAlg, &jso2);
2444 return_if_error(r, "Serialize TPMI_ALG_HASH");
2445
2446 json_object_object_add(*jso, "hashAlg", jso2);
2447 jso2 = NULL;
2448 r = ifapi_json_UINT16_serialize(in->count, &jso2);
2449 return_if_error(r, "Serialize UINT16");
2450
2451 json_object_object_add(*jso, "count", jso2);
2452 return TSS2_RC_SUCCESS;
2453 }
2454
2455 /** Serialize TPMI_ALG_KEYEDHASH_SCHEME to json.
2456 *
2457 * @param[in] in variable to be serialized.
2458 * @param[out] jso pointer to the json object.
2459 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2460 * the function.
2461 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2462 */
2463 TSS2_RC
2464 ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_serialize(const TPMI_ALG_KEYEDHASH_SCHEME in, json_object **jso)
2465 {
2466 CHECK_IN_LIST(TPMI_ALG_HASH, in, TPM2_ALG_HMAC, TPM2_ALG_XOR, TPM2_ALG_NULL);
2467 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
2468 }
2469
2470 /** Serialize a TPMS_SCHEME_HMAC to json.
2471 *
2472 * @param[in] in value of type TPMS_SCHEME_HMAC to be serialized.
2473 * @param[out] jso pointer to the json object.
2474 * @retval TSS2_RC_SUCCESS if the function call was a success.
2475 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2476 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SCHEME_HMAC.
2477 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2478 */
2479 TSS2_RC
2480 ifapi_json_TPMS_SCHEME_HMAC_serialize(const TPMS_SCHEME_HMAC *in, json_object **jso)
2481 {
2482 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2483 }
2484
2485 /** Serialize value of type TPMS_SCHEME_XOR to json.
2486 *
2487 * @param[in] in value to be serialized.
2488 * @param[out] jso pointer to the json object.
2489 * @retval TSS2_RC_SUCCESS if the function call was a success.
2490 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2491 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SCHEME_XOR.
2492 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2493 */
2494 TSS2_RC
2495 ifapi_json_TPMS_SCHEME_XOR_serialize(const TPMS_SCHEME_XOR *in, json_object **jso)
2496 {
2497 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2498
2499 TSS2_RC r;
2500 json_object *jso2;
2501 if (*jso == NULL)
2502 *jso = json_object_new_object ();
2503 jso2 = NULL;
2504 r = ifapi_json_TPMI_ALG_HASH_serialize(in->hashAlg, &jso2);
2505 return_if_error(r, "Serialize TPMI_ALG_HASH");
2506
2507 json_object_object_add(*jso, "hashAlg", jso2);
2508 jso2 = NULL;
2509 r = ifapi_json_TPMI_ALG_KDF_serialize(in->kdf, &jso2);
2510 return_if_error(r, "Serialize TPMI_ALG_KDF");
2511
2512 json_object_object_add(*jso, "kdf", jso2);
2513 return TSS2_RC_SUCCESS;
2514 }
2515
2516 /** Serialize a TPMU_SCHEME_KEYEDHASH to json.
2517 *
2518 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
2519 * @param[in] in the value to be serialized.
2520 * @param[in] selector the type of the keyedhash scheme.
2521 * @param[out] jso pointer to the json object.
2522 * @retval TSS2_RC_SUCCESS if the function call was a success.
2523 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2524 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_SCHEME_KEYEDHASH.
2525 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2526 */
2527 TSS2_RC
2528 ifapi_json_TPMU_SCHEME_KEYEDHASH_serialize(const TPMU_SCHEME_KEYEDHASH *in, UINT32 selector, json_object **jso)
2529 {
2530 switch (selector) {
2531 case TPM2_ALG_HMAC:
2532 return ifapi_json_TPMS_SCHEME_HMAC_serialize(&in->hmac, jso);
2533 case TPM2_ALG_XOR:
2534 return ifapi_json_TPMS_SCHEME_XOR_serialize(&in->exclusiveOr, jso);
2535 default:
2536 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
2537 return TSS2_FAPI_RC_BAD_VALUE;
2538 };
2539 return TSS2_RC_SUCCESS;
2540 }
2541
2542 /** Serialize value of type TPMT_KEYEDHASH_SCHEME to json.
2543 *
2544 * @param[in] in value to be serialized.
2545 * @param[out] jso pointer to the json object.
2546 * @retval TSS2_RC_SUCCESS if the function call was a success.
2547 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2548 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_KEYEDHASH_SCHEME.
2549 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2550 */
2551 TSS2_RC
2552 ifapi_json_TPMT_KEYEDHASH_SCHEME_serialize(const TPMT_KEYEDHASH_SCHEME *in, json_object **jso)
2553 {
2554 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2555
2556 TSS2_RC r;
2557 json_object *jso2;
2558 if (*jso == NULL)
2559 *jso = json_object_new_object ();
2560 jso2 = NULL;
2561 r = ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_serialize(in->scheme, &jso2);
2562 return_if_error(r, "Serialize TPMI_ALG_KEYEDHASH_SCHEME");
2563
2564 json_object_object_add(*jso, "scheme", jso2);
2565 if (in->scheme != TPM2_ALG_NULL) {
2566 json_object *jso2 = NULL;
2567 r = ifapi_json_TPMU_SCHEME_KEYEDHASH_serialize(&in->details, in->scheme, &jso2);
2568 return_if_error(r,"Serialize TPMU_SCHEME_KEYEDHASH");
2569
2570 json_object_object_add(*jso, "details", jso2);
2571 }
2572 return TSS2_RC_SUCCESS;
2573 }
2574
2575 /** Serialize a TPMS_SIG_SCHEME_RSASSA to json.
2576 *
2577 * @param[in] in value of type TPMS_SIG_SCHEME_RSASSA to be serialized.
2578 * @param[out] jso pointer to the json object.
2579 * @retval TSS2_RC_SUCCESS if the function call was a success.
2580 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2581 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIG_SCHEME_RSASSA.
2582 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2583 */
2584 TSS2_RC
2585 ifapi_json_TPMS_SIG_SCHEME_RSASSA_serialize(const TPMS_SIG_SCHEME_RSASSA *in, json_object **jso)
2586 {
2587 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2588 }
2589
2590 /** Serialize a TPMS_SIG_SCHEME_RSAPSS to json.
2591 *
2592 * @param[in] in value of type TPMS_SIG_SCHEME_RSAPSS to be serialized.
2593 * @param[out] jso pointer to the json object.
2594 * @retval TSS2_RC_SUCCESS if the function call was a success.
2595 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2596 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIG_SCHEME_RSAPSS.
2597 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2598 */
2599 TSS2_RC
2600 ifapi_json_TPMS_SIG_SCHEME_RSAPSS_serialize(const TPMS_SIG_SCHEME_RSAPSS *in, json_object **jso)
2601 {
2602 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2603 }
2604
2605 /** Serialize a TPMS_SIG_SCHEME_ECDSA to json.
2606 *
2607 * @param[in] in value of type TPMS_SIG_SCHEME_ECDSA to be serialized.
2608 * @param[out] jso pointer to the json object.
2609 * @retval TSS2_RC_SUCCESS if the function call was a success.
2610 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2611 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIG_SCHEME_ECDSA.
2612 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2613 */
2614 TSS2_RC
2615 ifapi_json_TPMS_SIG_SCHEME_ECDSA_serialize(const TPMS_SIG_SCHEME_ECDSA *in, json_object **jso)
2616 {
2617 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2618 }
2619
2620 /** Serialize a TPMS_SIG_SCHEME_SM2 to json.
2621 *
2622 * @param[in] in value of type TPMS_SIG_SCHEME_SM2 to be serialized.
2623 * @param[out] jso pointer to the json object.
2624 * @retval TSS2_RC_SUCCESS if the function call was a success.
2625 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2626 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIG_SCHEME_SM2.
2627 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2628 */
2629 TSS2_RC
2630 ifapi_json_TPMS_SIG_SCHEME_SM2_serialize(const TPMS_SIG_SCHEME_SM2 *in, json_object **jso)
2631 {
2632 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2633 }
2634
2635 /** Serialize a TPMS_SIG_SCHEME_ECSCHNORR to json.
2636 *
2637 * @param[in] in value of type TPMS_SIG_SCHEME_ECSCHNORR to be serialized.
2638 * @param[out] jso pointer to the json object.
2639 * @retval TSS2_RC_SUCCESS if the function call was a success.
2640 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2641 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIG_SCHEME_ECSCHNORR.
2642 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2643 */
2644 TSS2_RC
2645 ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_serialize(const TPMS_SIG_SCHEME_ECSCHNORR *in, json_object **jso)
2646 {
2647 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2648 }
2649
2650 /** Serialize a TPMS_SIG_SCHEME_ECDAA to json.
2651 *
2652 * @param[in] in value of type TPMS_SIG_SCHEME_ECDAA to be serialized.
2653 * @param[out] jso pointer to the json object.
2654 * @retval TSS2_RC_SUCCESS if the function call was a success.
2655 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2656 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIG_SCHEME_ECDAA.
2657 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2658 */
2659 TSS2_RC
2660 ifapi_json_TPMS_SIG_SCHEME_ECDAA_serialize(const TPMS_SIG_SCHEME_ECDAA *in, json_object **jso)
2661 {
2662 return ifapi_json_TPMS_SCHEME_ECDAA_serialize(in, jso);
2663 }
2664
2665 /** Serialize a TPMU_SIG_SCHEME to json.
2666 *
2667 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
2668 * @param[in] in the value to be serialized.
2669 * @param[in] selector the type of the signature scheme.
2670 * @param[out] jso pointer to the json object.
2671 * @retval TSS2_RC_SUCCESS if the function call was a success.
2672 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2673 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_SIG_SCHEME.
2674 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2675 */
2676 TSS2_RC
2677 ifapi_json_TPMU_SIG_SCHEME_serialize(const TPMU_SIG_SCHEME *in, UINT32 selector, json_object **jso)
2678 {
2679 switch (selector) {
2680 case TPM2_ALG_RSASSA:
2681 return ifapi_json_TPMS_SIG_SCHEME_RSASSA_serialize(&in->rsassa, jso);
2682 case TPM2_ALG_RSAPSS:
2683 return ifapi_json_TPMS_SIG_SCHEME_RSAPSS_serialize(&in->rsapss, jso);
2684 case TPM2_ALG_ECDSA:
2685 return ifapi_json_TPMS_SIG_SCHEME_ECDSA_serialize(&in->ecdsa, jso);
2686 case TPM2_ALG_ECDAA:
2687 return ifapi_json_TPMS_SIG_SCHEME_ECDAA_serialize(&in->ecdaa, jso);
2688 case TPM2_ALG_SM2:
2689 return ifapi_json_TPMS_SIG_SCHEME_SM2_serialize(&in->sm2, jso);
2690 case TPM2_ALG_ECSCHNORR:
2691 return ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_serialize(&in->ecschnorr, jso);
2692 case TPM2_ALG_HMAC:
2693 return ifapi_json_TPMS_SCHEME_HMAC_serialize(&in->hmac, jso);
2694 default:
2695 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
2696 return TSS2_FAPI_RC_BAD_VALUE;
2697 };
2698 return TSS2_RC_SUCCESS;
2699 }
2700
2701 /** Serialize value of type TPMT_SIG_SCHEME to json.
2702 *
2703 * @param[in] in value to be serialized.
2704 * @param[out] jso pointer to the json object.
2705 * @retval TSS2_RC_SUCCESS if the function call was a success.
2706 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2707 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_SIG_SCHEME.
2708 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2709 */
2710 TSS2_RC
2711 ifapi_json_TPMT_SIG_SCHEME_serialize(const TPMT_SIG_SCHEME *in, json_object **jso)
2712 {
2713 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2714
2715 TSS2_RC r;
2716 json_object *jso2;
2717 if (*jso == NULL)
2718 *jso = json_object_new_object ();
2719 jso2 = NULL;
2720 r = ifapi_json_TPMI_ALG_SIG_SCHEME_serialize(in->scheme, &jso2);
2721 return_if_error(r, "Serialize TPMI_ALG_SIG_SCHEME");
2722
2723 json_object_object_add(*jso, "scheme", jso2);
2724 if (in->scheme != TPM2_ALG_NULL) {
2725 json_object *jso2 = NULL;
2726 r = ifapi_json_TPMU_SIG_SCHEME_serialize(&in->details, in->scheme, &jso2);
2727 return_if_error(r,"Serialize TPMU_SIG_SCHEME");
2728
2729 json_object_object_add(*jso, "details", jso2);
2730 }
2731 return TSS2_RC_SUCCESS;
2732 }
2733
2734 /** Serialize a TPMS_ENC_SCHEME_OAEP to json.
2735 *
2736 * @param[in] in value of type TPMS_ENC_SCHEME_OAEP to be serialized.
2737 * @param[out] jso pointer to the json object.
2738 * @retval TSS2_RC_SUCCESS if the function call was a success.
2739 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2740 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_ENC_SCHEME_OAEP.
2741 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2742 */
2743 TSS2_RC
2744 ifapi_json_TPMS_ENC_SCHEME_OAEP_serialize(const TPMS_ENC_SCHEME_OAEP *in, json_object **jso)
2745 {
2746 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2747 }
2748
2749 /** Serialize a TPMS_ENC_SCHEME_RSAES to json.
2750 *
2751 * @param[in] in value of type TPMS_ENC_SCHEME_RSAES to be serialized.
2752 * @param[out] jso pointer to the json object.
2753 * @retval TSS2_RC_SUCCESS if the function call was a success.
2754 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2755 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_ENC_SCHEME_RSAES.
2756 */
2757 TSS2_RC
2758 ifapi_json_TPMS_ENC_SCHEME_RSAES_serialize(const TPMS_ENC_SCHEME_RSAES *in, json_object **jso)
2759 {
2760 return ifapi_json_TPMS_EMPTY_serialize(in, jso);
2761 }
2762
2763 /** Serialize a TPMS_KEY_SCHEME_ECDH to json.
2764 *
2765 * @param[in] in value of type TPMS_KEY_SCHEME_ECDH to be serialized.
2766 * @param[out] jso pointer to the json object.
2767 * @retval TSS2_RC_SUCCESS if the function call was a success.
2768 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2769 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_KEY_SCHEME_ECDH.
2770 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2771 */
2772 TSS2_RC
2773 ifapi_json_TPMS_KEY_SCHEME_ECDH_serialize(const TPMS_KEY_SCHEME_ECDH *in, json_object **jso)
2774 {
2775 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2776 }
2777
2778 /** Serialize a TPMS_SCHEME_MGF1 to json.
2779 *
2780 * @param[in] in value of type TPMS_SCHEME_MGF1 to be serialized.
2781 * @param[out] jso pointer to the json object.
2782 * @retval TSS2_RC_SUCCESS if the function call was a success.
2783 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2784 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SCHEME_MGF1.
2785 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2786 */
2787 TSS2_RC
2788 ifapi_json_TPMS_SCHEME_MGF1_serialize(const TPMS_SCHEME_MGF1 *in, json_object **jso)
2789 {
2790 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2791 }
2792
2793 /** Serialize a TPMS_SCHEME_KDF1_SP800_56A to json.
2794 *
2795 * @param[in] in value of type TPMS_SCHEME_KDF1_SP800_56A to be serialized.
2796 * @param[out] jso pointer to the json object.
2797 * @retval TSS2_RC_SUCCESS if the function call was a success.
2798 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2799 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SCHEME_KDF1_SP800_56A.
2800 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2801 */
2802 TSS2_RC
2803 ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_serialize(const TPMS_SCHEME_KDF1_SP800_56A *in, json_object **jso)
2804 {
2805 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2806 }
2807
2808 /** Serialize a TPMS_SCHEME_KDF1_SP800_108 to json.
2809 *
2810 * @param[in] in value of type TPMS_SCHEME_KDF1_SP800_108 to be serialized.
2811 * @param[out] jso pointer to the json object.
2812 * @retval TSS2_RC_SUCCESS if the function call was a success.
2813 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2814 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SCHEME_KDF1_SP800_108.
2815 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2816 */
2817 TSS2_RC
2818 ifapi_json_TPMS_SCHEME_KDF1_SP800_108_serialize(const TPMS_SCHEME_KDF1_SP800_108 *in, json_object **jso)
2819 {
2820 return ifapi_json_TPMS_SCHEME_HASH_serialize(in, jso);
2821 }
2822
2823 /** Serialize a TPMU_KDF_SCHEME to json.
2824 *
2825 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
2826 * @param[in] in the value to be serialized.
2827 * @param[in] selector the type of the KDF scheme.
2828 * @param[out] jso pointer to the json object.
2829 * @retval TSS2_RC_SUCCESS if the function call was a success.
2830 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2831 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_KDF_SCHEME.
2832 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2833 */
2834 TSS2_RC
2835 ifapi_json_TPMU_KDF_SCHEME_serialize(const TPMU_KDF_SCHEME *in, UINT32 selector, json_object **jso)
2836 {
2837 switch (selector) {
2838 case TPM2_ALG_MGF1:
2839 return ifapi_json_TPMS_SCHEME_MGF1_serialize(&in->mgf1, jso);
2840 case TPM2_ALG_KDF1_SP800_56A:
2841 return ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_serialize(&in->kdf1_sp800_56a, jso);
2842 case TPM2_ALG_KDF1_SP800_108:
2843 return ifapi_json_TPMS_SCHEME_KDF1_SP800_108_serialize(&in->kdf1_sp800_108, jso);
2844 default:
2845 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
2846 return TSS2_FAPI_RC_BAD_VALUE;
2847 };
2848 return TSS2_RC_SUCCESS;
2849 }
2850
2851 /** Serialize value of type TPMT_KDF_SCHEME to json.
2852 *
2853 * @param[in] in value to be serialized.
2854 * @param[out] jso pointer to the json object.
2855 * @retval TSS2_RC_SUCCESS if the function call was a success.
2856 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2857 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_KDF_SCHEME.
2858 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2859 */
2860 TSS2_RC
2861 ifapi_json_TPMT_KDF_SCHEME_serialize(const TPMT_KDF_SCHEME *in, json_object **jso)
2862 {
2863 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2864
2865 TSS2_RC r;
2866 json_object *jso2;
2867 if (*jso == NULL)
2868 *jso = json_object_new_object ();
2869 jso2 = NULL;
2870 r = ifapi_json_TPMI_ALG_KDF_serialize(in->scheme, &jso2);
2871 return_if_error(r, "Serialize TPMI_ALG_KDF");
2872
2873 json_object_object_add(*jso, "scheme", jso2);
2874 if (in->scheme != TPM2_ALG_NULL) {
2875 json_object *jso2 = NULL;
2876 r = ifapi_json_TPMU_KDF_SCHEME_serialize(&in->details, in->scheme, &jso2);
2877 return_if_error(r,"Serialize TPMU_KDF_SCHEME");
2878
2879 json_object_object_add(*jso, "details", jso2);
2880 }
2881 return TSS2_RC_SUCCESS;
2882 }
2883
2884 /** Serialize TPMI_ALG_ASYM_SCHEME to json.
2885 *
2886 * @param[in] in variable to be serialized.
2887 * @param[out] jso pointer to the json object.
2888 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2889 * the function.
2890 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2891 */
2892 TSS2_RC
2893 ifapi_json_TPMI_ALG_ASYM_SCHEME_serialize(const TPMI_ALG_ASYM_SCHEME in, json_object **jso)
2894 {
2895 CHECK_IN_LIST(TPMI_ALG_ASYM_SCHEME, in, TPM2_ALG_ECDH, TPM2_ALG_RSASSA, TPM2_ALG_RSAPSS,
2896 TPM2_ALG_ECDSA, TPM2_ALG_ECDAA, TPM2_ALG_SM2, TPM2_ALG_ECSCHNORR,
2897 TPM2_ALG_RSAES, TPM2_ALG_OAEP, TPM2_ALG_NULL);
2898 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
2899 }
2900
2901 /** Serialize a TPMU_ASYM_SCHEME to json.
2902 *
2903 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
2904 * @param[in] in the value to be serialized.
2905 * @param[in] selector the type of the scheme.
2906 * @param[out] jso pointer to the json object.
2907 * @retval TSS2_RC_SUCCESS if the function call was a success.
2908 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2909 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_ASYM_SCHEME.
2910 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2911 */
2912 TSS2_RC
2913 ifapi_json_TPMU_ASYM_SCHEME_serialize(const TPMU_ASYM_SCHEME *in, UINT32 selector, json_object **jso)
2914 {
2915 switch (selector) {
2916 case TPM2_ALG_ECDH:
2917 return ifapi_json_TPMS_KEY_SCHEME_ECDH_serialize(&in->ecdh, jso);
2918 case TPM2_ALG_RSASSA:
2919 return ifapi_json_TPMS_SIG_SCHEME_RSASSA_serialize(&in->rsassa, jso);
2920 case TPM2_ALG_RSAPSS:
2921 return ifapi_json_TPMS_SIG_SCHEME_RSAPSS_serialize(&in->rsapss, jso);
2922 case TPM2_ALG_ECDSA:
2923 return ifapi_json_TPMS_SIG_SCHEME_ECDSA_serialize(&in->ecdsa, jso);
2924 case TPM2_ALG_ECDAA:
2925 return ifapi_json_TPMS_SIG_SCHEME_ECDAA_serialize(&in->ecdaa, jso);
2926 case TPM2_ALG_SM2:
2927 return ifapi_json_TPMS_SIG_SCHEME_SM2_serialize(&in->sm2, jso);
2928 case TPM2_ALG_ECSCHNORR:
2929 return ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_serialize(&in->ecschnorr, jso);
2930 case TPM2_ALG_RSAES:
2931 return ifapi_json_TPMS_ENC_SCHEME_RSAES_serialize(&in->rsaes, jso);
2932 case TPM2_ALG_OAEP:
2933 return ifapi_json_TPMS_ENC_SCHEME_OAEP_serialize(&in->oaep, jso);
2934 default:
2935 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
2936 return TSS2_FAPI_RC_BAD_VALUE;
2937 };
2938 return TSS2_RC_SUCCESS;
2939 }
2940
2941 /** Serialize value of type TPMT_ASYM_SCHEME to json.
2942 *
2943 * @param[in] in value to be serialized.
2944 * @param[out] jso pointer to the json object.
2945 * @retval TSS2_RC_SUCCESS if the function call was a success.
2946 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2947 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_ASYM_SCHEME.
2948 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2949 */
2950 TSS2_RC
2951 ifapi_json_TPMT_ASYM_SCHEME_serialize(const TPMT_ASYM_SCHEME *in, json_object **jso)
2952 {
2953 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
2954
2955 TSS2_RC r;
2956 json_object *jso2;
2957 if (*jso == NULL)
2958 *jso = json_object_new_object ();
2959 jso2 = NULL;
2960 r = ifapi_json_TPMI_ALG_ASYM_SCHEME_serialize(in->scheme, &jso2);
2961 return_if_error(r, "Serialize TPMI_ALG_ASYM_SCHEME");
2962
2963 json_object_object_add(*jso, "scheme", jso2);
2964 if (in->scheme != TPM2_ALG_NULL) {
2965 json_object *jso2 = NULL;
2966 r = ifapi_json_TPMU_ASYM_SCHEME_serialize(&in->details, in->scheme, &jso2);
2967 return_if_error(r,"Serialize TPMU_ASYM_SCHEME");
2968
2969 json_object_object_add(*jso, "details", jso2);
2970 }
2971 return TSS2_RC_SUCCESS;
2972 }
2973
2974 /** Serialize TPMI_ALG_RSA_SCHEME to json.
2975 *
2976 * @param[in] in variable to be serialized.
2977 * @param[out] jso pointer to the json object.
2978 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
2979 * the function.
2980 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
2981 */
2982 TSS2_RC
2983 ifapi_json_TPMI_ALG_RSA_SCHEME_serialize(const TPMI_ALG_RSA_SCHEME in, json_object **jso)
2984 {
2985 CHECK_IN_LIST(TPMI_ALG_RSA_SCHEME, in, TPM2_ALG_RSAES, TPM2_ALG_OAEP, TPM2_ALG_RSASSA,
2986 TPM2_ALG_RSAPSS, TPM2_ALG_NULL);
2987 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
2988 }
2989
2990 /** Serialize value of type TPMT_RSA_SCHEME to json.
2991 *
2992 * @param[in] in value to be serialized.
2993 * @param[out] jso pointer to the json object.
2994 * @retval TSS2_RC_SUCCESS if the function call was a success.
2995 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
2996 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_RSA_SCHEME.
2997 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
2998 */
2999 TSS2_RC
3000 ifapi_json_TPMT_RSA_SCHEME_serialize(const TPMT_RSA_SCHEME *in, json_object **jso)
3001 {
3002 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3003
3004 TSS2_RC r;
3005 json_object *jso2;
3006 if (*jso == NULL)
3007 *jso = json_object_new_object ();
3008 jso2 = NULL;
3009 r = ifapi_json_TPMI_ALG_RSA_SCHEME_serialize(in->scheme, &jso2);
3010 return_if_error(r, "Serialize TPMI_ALG_RSA_SCHEME");
3011
3012 json_object_object_add(*jso, "scheme", jso2);
3013 if (in->scheme != TPM2_ALG_NULL) {
3014 json_object *jso2 = NULL;
3015 r = ifapi_json_TPMU_ASYM_SCHEME_serialize(&in->details, in->scheme, &jso2);
3016 return_if_error(r,"Serialize TPMU_ASYM_SCHEME");
3017
3018 json_object_object_add(*jso, "details", jso2);
3019 }
3020 return TSS2_RC_SUCCESS;
3021 }
3022
3023 /** Serialize value of type TPM2B_PUBLIC_KEY_RSA to json.
3024 *
3025 * @param[in] in value to be serialized.
3026 * @param[out] jso pointer to the json object.
3027 * @retval TSS2_RC_SUCCESS if the function call was a success.
3028 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3029 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_PUBLIC_KEY_RSA.
3030 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3031 */
3032 TSS2_RC
3033 ifapi_json_TPM2B_PUBLIC_KEY_RSA_serialize(const TPM2B_PUBLIC_KEY_RSA *in, json_object **jso)
3034 {
3035 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3036
3037 if (in->size > TPM2_MAX_RSA_KEY_BYTES) {
3038 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_RSA_KEY_BYTES)",
3039 (size_t)in->size, (size_t)TPM2_MAX_RSA_KEY_BYTES);
3040 return TSS2_FAPI_RC_BAD_VALUE;
3041 }
3042 char hex_string[((size_t)in->size)*2+1];
3043
3044 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
3045 sprintf(&hex_string[off], "%02x", in->buffer[i]);
3046 hex_string[(in->size)*2] = '\0';
3047 *jso = json_object_new_string (hex_string);
3048 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3049
3050 return TSS2_RC_SUCCESS;
3051 }
3052
3053 /** Serialize value of type TPMI_RSA_KEY_BITS to json.
3054 *
3055 * @param[in] in value to be serialized.
3056 * @param[out] jso pointer to the json object.
3057 * @retval TSS2_RC_SUCCESS if the function call was a success.
3058 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3059 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMI_RSA_KEY_BITS.
3060 *
3061 */
3062 TSS2_RC
3063 ifapi_json_TPMI_RSA_KEY_BITS_serialize(const TPMI_RSA_KEY_BITS in, json_object **jso)
3064 {
3065 CHECK_IN_LIST(TPMI_RSA_KEY_BITS, in, 1024, 2048);
3066 return ifapi_json_UINT16_serialize(in, jso);
3067 }
3068
3069 /** Serialize value of type TPM2B_ECC_PARAMETER to json.
3070 *
3071 * @param[in] in value to be serialized.
3072 * @param[out] jso pointer to the json object.
3073 * @retval TSS2_RC_SUCCESS if the function call was a success.
3074 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3075 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_ECC_PARAMETER.
3076 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3077 */
3078 TSS2_RC
3079 ifapi_json_TPM2B_ECC_PARAMETER_serialize(const TPM2B_ECC_PARAMETER *in, json_object **jso)
3080 {
3081 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3082
3083 if (in->size > TPM2_MAX_ECC_KEY_BYTES) {
3084 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = TPM2_MAX_ECC_KEY_BYTES)",
3085 (size_t)in->size, (size_t)TPM2_MAX_ECC_KEY_BYTES);
3086 return TSS2_FAPI_RC_BAD_VALUE;
3087 }
3088 char hex_string[((size_t)in->size)*2+1];
3089
3090 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
3091 sprintf(&hex_string[off], "%02x", in->buffer[i]);
3092 hex_string[(in->size)*2] = '\0';
3093 *jso = json_object_new_string (hex_string);
3094 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3095
3096 return TSS2_RC_SUCCESS;
3097 }
3098
3099 /** Serialize value of type TPMS_ECC_POINT to json.
3100 *
3101 * @param[in] in value to be serialized.
3102 * @param[out] jso pointer to the json object.
3103 * @retval TSS2_RC_SUCCESS if the function call was a success.
3104 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3105 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_ECC_POINT.
3106 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3107 */
3108 TSS2_RC
3109 ifapi_json_TPMS_ECC_POINT_serialize(const TPMS_ECC_POINT *in, json_object **jso)
3110 {
3111 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3112
3113 TSS2_RC r;
3114 json_object *jso2;
3115 if (*jso == NULL)
3116 *jso = json_object_new_object ();
3117 jso2 = NULL;
3118 r = ifapi_json_TPM2B_ECC_PARAMETER_serialize(&in->x, &jso2);
3119 return_if_error(r, "Serialize TPM2B_ECC_PARAMETER");
3120
3121 json_object_object_add(*jso, "x", jso2);
3122 jso2 = NULL;
3123 r = ifapi_json_TPM2B_ECC_PARAMETER_serialize(&in->y, &jso2);
3124 return_if_error(r, "Serialize TPM2B_ECC_PARAMETER");
3125
3126 json_object_object_add(*jso, "y", jso2);
3127 return TSS2_RC_SUCCESS;
3128 }
3129
3130 /** Serialize TPMI_ALG_ECC_SCHEME to json.
3131 *
3132 * @param[in] in variable to be serialized.
3133 * @param[out] jso pointer to the json object.
3134 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
3135 * the function.
3136 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
3137 */
3138 TSS2_RC
3139 ifapi_json_TPMI_ALG_ECC_SCHEME_serialize(const TPMI_ALG_ECC_SCHEME in, json_object **jso)
3140 {
3141 CHECK_IN_LIST(TPMI_ALG_ECC_SCHEME, in, TPM2_ALG_ECDSA, TPM2_ALG_ECDAA,
3142 TPM2_ALG_SM2, TPM2_ALG_ECSCHNORR, TPM2_ALG_ECDH, TPM2_ALG_NULL);
3143 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
3144 }
3145
3146 /** Serialize value of type TPMI_ECC_CURVE to json.
3147 *
3148 * @param[in] in value to be serialized.
3149 * @param[out] jso pointer to the json object.
3150 * @retval TSS2_RC_SUCCESS if the function call was a success.
3151 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3152 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMI_ECC_CURVE.
3153 *
3154 */
3155 TSS2_RC
3156 ifapi_json_TPMI_ECC_CURVE_serialize(const TPMI_ECC_CURVE in, json_object **jso)
3157 {
3158 return ifapi_json_TPM2_ECC_CURVE_serialize(in, jso);
3159 }
3160
3161 /** Serialize value of type TPMT_ECC_SCHEME to json.
3162 *
3163 * @param[in] in value to be serialized.
3164 * @param[out] jso pointer to the json object.
3165 * @retval TSS2_RC_SUCCESS if the function call was a success.
3166 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3167 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_ECC_SCHEME.
3168 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3169 */
3170 TSS2_RC
3171 ifapi_json_TPMT_ECC_SCHEME_serialize(const TPMT_ECC_SCHEME *in, json_object **jso)
3172 {
3173 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3174
3175 TSS2_RC r;
3176 json_object *jso2;
3177 if (*jso == NULL)
3178 *jso = json_object_new_object ();
3179 jso2 = NULL;
3180 r = ifapi_json_TPMI_ALG_ECC_SCHEME_serialize(in->scheme, &jso2);
3181 return_if_error(r, "Serialize TPMI_ALG_ECC_SCHEME");
3182
3183 json_object_object_add(*jso, "scheme", jso2);
3184 if (in->scheme != TPM2_ALG_NULL) {
3185 json_object *jso2 = NULL;
3186 r = ifapi_json_TPMU_ASYM_SCHEME_serialize(&in->details, in->scheme, &jso2);
3187 return_if_error(r,"Serialize TPMU_ASYM_SCHEME");
3188
3189 json_object_object_add(*jso, "details", jso2);
3190 }
3191 return TSS2_RC_SUCCESS;
3192 }
3193
3194 /** Serialize value of type TPMS_SIGNATURE_RSA to json.
3195 *
3196 * @param[in] in value to be serialized.
3197 * @param[out] jso pointer to the json object.
3198 * @retval TSS2_RC_SUCCESS if the function call was a success.
3199 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3200 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_RSA.
3201 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3202 */
3203 TSS2_RC
3204 ifapi_json_TPMS_SIGNATURE_RSA_serialize(const TPMS_SIGNATURE_RSA *in, json_object **jso)
3205 {
3206 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3207
3208 TSS2_RC r;
3209 json_object *jso2;
3210 if (*jso == NULL)
3211 *jso = json_object_new_object ();
3212 jso2 = NULL;
3213 r = ifapi_json_TPMI_ALG_HASH_serialize(in->hash, &jso2);
3214 return_if_error(r, "Serialize TPMI_ALG_HASH");
3215
3216 json_object_object_add(*jso, "hash", jso2);
3217 jso2 = NULL;
3218 r = ifapi_json_TPM2B_PUBLIC_KEY_RSA_serialize(&in->sig, &jso2);
3219 return_if_error(r, "Serialize TPM2B_PUBLIC_KEY_RSA");
3220
3221 json_object_object_add(*jso, "sig", jso2);
3222 return TSS2_RC_SUCCESS;
3223 }
3224
3225 /** Serialize a TPMS_SIGNATURE_RSASSA to json.
3226 *
3227 * @param[in] in value of type TPMS_SIGNATURE_RSASSA to be serialized.
3228 * @param[out] jso pointer to the json object.
3229 * @retval TSS2_RC_SUCCESS if the function call was a success.
3230 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3231 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_RSASSA.
3232 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3233 */
3234 TSS2_RC
3235 ifapi_json_TPMS_SIGNATURE_RSASSA_serialize(const TPMS_SIGNATURE_RSASSA *in, json_object **jso)
3236 {
3237 return ifapi_json_TPMS_SIGNATURE_RSA_serialize(in, jso);
3238 }
3239
3240 /** Serialize a TPMS_SIGNATURE_RSAPSS to json.
3241 *
3242 * @param[in] in value of type TPMS_SIGNATURE_RSAPSS to be serialized.
3243 * @param[out] jso pointer to the json object.
3244 * @retval TSS2_RC_SUCCESS if the function call was a success.
3245 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3246 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_RSAPSS.
3247 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3248 */
3249 TSS2_RC
3250 ifapi_json_TPMS_SIGNATURE_RSAPSS_serialize(const TPMS_SIGNATURE_RSAPSS *in, json_object **jso)
3251 {
3252 return ifapi_json_TPMS_SIGNATURE_RSA_serialize(in, jso);
3253 }
3254
3255 /** Serialize value of type TPMS_SIGNATURE_ECC to json.
3256 *
3257 * @param[in] in value to be serialized.
3258 * @param[out] jso pointer to the json object.
3259 * @retval TSS2_RC_SUCCESS if the function call was a success.
3260 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3261 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_ECC.
3262 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3263 */
3264 TSS2_RC
3265 ifapi_json_TPMS_SIGNATURE_ECC_serialize(const TPMS_SIGNATURE_ECC *in, json_object **jso)
3266 {
3267 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3268
3269 TSS2_RC r;
3270 json_object *jso2;
3271 if (*jso == NULL)
3272 *jso = json_object_new_object ();
3273 jso2 = NULL;
3274 r = ifapi_json_TPMI_ALG_HASH_serialize(in->hash, &jso2);
3275 return_if_error(r, "Serialize TPMI_ALG_HASH");
3276
3277 json_object_object_add(*jso, "hash", jso2);
3278 jso2 = NULL;
3279 r = ifapi_json_TPM2B_ECC_PARAMETER_serialize(&in->signatureR, &jso2);
3280 return_if_error(r, "Serialize TPM2B_ECC_PARAMETER");
3281
3282 json_object_object_add(*jso, "signatureR", jso2);
3283 jso2 = NULL;
3284 r = ifapi_json_TPM2B_ECC_PARAMETER_serialize(&in->signatureS, &jso2);
3285 return_if_error(r, "Serialize TPM2B_ECC_PARAMETER");
3286
3287 json_object_object_add(*jso, "signatureS", jso2);
3288 return TSS2_RC_SUCCESS;
3289 }
3290
3291 /** Serialize a TPMS_SIGNATURE_ECDSA to json.
3292 *
3293 * @param[in] in value of type TPMS_SIGNATURE_ECDSA to be serialized.
3294 * @param[out] jso pointer to the json object.
3295 * @retval TSS2_RC_SUCCESS if the function call was a success.
3296 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3297 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_ECDSA.
3298 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3299 */
3300 TSS2_RC
3301 ifapi_json_TPMS_SIGNATURE_ECDSA_serialize(const TPMS_SIGNATURE_ECDSA *in, json_object **jso)
3302 {
3303 return ifapi_json_TPMS_SIGNATURE_ECC_serialize(in, jso);
3304 }
3305
3306 /** Serialize a TPMS_SIGNATURE_ECDAA to json.
3307 *
3308 * @param[in] in value of type TPMS_SIGNATURE_ECDAA to be serialized.
3309 * @param[out] jso pointer to the json object.
3310 * @retval TSS2_RC_SUCCESS if the function call was a success.
3311 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3312 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_ECDAA.
3313 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3314 */
3315 TSS2_RC
3316 ifapi_json_TPMS_SIGNATURE_ECDAA_serialize(const TPMS_SIGNATURE_ECDAA *in, json_object **jso)
3317 {
3318 return ifapi_json_TPMS_SIGNATURE_ECC_serialize(in, jso);
3319 }
3320
3321 /** Serialize a TPMS_SIGNATURE_SM2 to json.
3322 *
3323 * @param[in] in value of type TPMS_SIGNATURE_SM2 to be serialized.
3324 * @param[out] jso pointer to the json object.
3325 * @retval TSS2_RC_SUCCESS if the function call was a success.
3326 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3327 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_SM2.
3328 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3329 */
3330 TSS2_RC
3331 ifapi_json_TPMS_SIGNATURE_SM2_serialize(const TPMS_SIGNATURE_SM2 *in, json_object **jso)
3332 {
3333 return ifapi_json_TPMS_SIGNATURE_ECC_serialize(in, jso);
3334 }
3335
3336 /** Serialize a TPMS_SIGNATURE_ECSCHNORR to json.
3337 *
3338 * @param[in] in value of type TPMS_SIGNATURE_ECSCHNORR to be serialized.
3339 * @param[out] jso pointer to the json object.
3340 * @retval TSS2_RC_SUCCESS if the function call was a success.
3341 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3342 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_SIGNATURE_ECSCHNORR.
3343 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3344 */
3345 TSS2_RC
3346 ifapi_json_TPMS_SIGNATURE_ECSCHNORR_serialize(const TPMS_SIGNATURE_ECSCHNORR *in, json_object **jso)
3347 {
3348 return ifapi_json_TPMS_SIGNATURE_ECC_serialize(in, jso);
3349 }
3350
3351 /** Serialize a TPMU_SIGNATURE to json.
3352 *
3353 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
3354 * @param[in] in the value to be serialized.
3355 * @param[in] selector the type of the signature.
3356 * @param[out] jso pointer to the json object.
3357 * @retval TSS2_RC_SUCCESS if the function call was a success.
3358 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3359 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_SIGNATURE.
3360 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3361 */
3362 TSS2_RC
3363 ifapi_json_TPMU_SIGNATURE_serialize(const TPMU_SIGNATURE *in, UINT32 selector, json_object **jso)
3364 {
3365 switch (selector) {
3366 case TPM2_ALG_RSASSA:
3367 return ifapi_json_TPMS_SIGNATURE_RSASSA_serialize(&in->rsassa, jso);
3368 case TPM2_ALG_RSAPSS:
3369 return ifapi_json_TPMS_SIGNATURE_RSAPSS_serialize(&in->rsapss, jso);
3370 case TPM2_ALG_ECDSA:
3371 return ifapi_json_TPMS_SIGNATURE_ECDSA_serialize(&in->ecdsa, jso);
3372 case TPM2_ALG_ECDAA:
3373 return ifapi_json_TPMS_SIGNATURE_ECDAA_serialize(&in->ecdaa, jso);
3374 case TPM2_ALG_SM2:
3375 return ifapi_json_TPMS_SIGNATURE_SM2_serialize(&in->sm2, jso);
3376 case TPM2_ALG_ECSCHNORR:
3377 return ifapi_json_TPMS_SIGNATURE_ECSCHNORR_serialize(&in->ecschnorr, jso);
3378 case TPM2_ALG_HMAC:
3379 return ifapi_json_TPMT_HA_serialize(&in->hmac, jso);
3380 default:
3381 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
3382 return TSS2_FAPI_RC_BAD_VALUE;
3383 };
3384 return TSS2_RC_SUCCESS;
3385 }
3386
3387 /** Serialize value of type TPMT_SIGNATURE to json.
3388 *
3389 * @param[in] in value to be serialized.
3390 * @param[out] jso pointer to the json object.
3391 * @retval TSS2_RC_SUCCESS if the function call was a success.
3392 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3393 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_SIGNATURE.
3394 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3395 */
3396 TSS2_RC
3397 ifapi_json_TPMT_SIGNATURE_serialize(const TPMT_SIGNATURE *in, json_object **jso)
3398 {
3399 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3400
3401 TSS2_RC r;
3402 json_object *jso2;
3403 if (*jso == NULL)
3404 *jso = json_object_new_object ();
3405 jso2 = NULL;
3406 r = ifapi_json_TPMI_ALG_SIG_SCHEME_serialize(in->sigAlg, &jso2);
3407 return_if_error(r, "Serialize TPMI_ALG_SIG_SCHEME");
3408
3409 json_object_object_add(*jso, "sigAlg", jso2);
3410 if (in->sigAlg != TPM2_ALG_NULL) {
3411 json_object *jso2 = NULL;
3412 r = ifapi_json_TPMU_SIGNATURE_serialize(&in->signature, in->sigAlg, &jso2);
3413 return_if_error(r,"Serialize TPMU_SIGNATURE");
3414
3415 json_object_object_add(*jso, "signature", jso2);
3416 }
3417 return TSS2_RC_SUCCESS;
3418 }
3419
3420 /** Serialize value of type TPM2B_ENCRYPTED_SECRET to json.
3421 *
3422 * @param[in] in value to be serialized.
3423 * @param[out] jso pointer to the json object.
3424 * @retval TSS2_RC_SUCCESS if the function call was a success.
3425 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3426 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_ENCRYPTED_SECRET.
3427 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3428 */
3429 TSS2_RC
3430 ifapi_json_TPM2B_ENCRYPTED_SECRET_serialize(const TPM2B_ENCRYPTED_SECRET *in, json_object **jso)
3431 {
3432 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3433
3434 if (in->size > sizeof(TPMU_ENCRYPTED_SECRET)) {
3435 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = sizeof(TPMU_ENCRYPTED_SECRET))",
3436 (size_t)in->size, (size_t)sizeof(TPMU_ENCRYPTED_SECRET));
3437 return TSS2_FAPI_RC_BAD_VALUE;
3438 }
3439 char hex_string[((size_t)in->size)*2+1];
3440
3441 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
3442 sprintf(&hex_string[off], "%02x", in->secret[i]);
3443 hex_string[(in->size)*2] = '\0';
3444 *jso = json_object_new_string (hex_string);
3445 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3446
3447 return TSS2_RC_SUCCESS;
3448 }
3449
3450 /** Serialize TPMI_ALG_PUBLIC to json.
3451 *
3452 * @param[in] in variable to be serialized.
3453 * @param[out] jso pointer to the json object.
3454 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
3455 * the function.
3456 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
3457 */
3458 TSS2_RC
3459 ifapi_json_TPMI_ALG_PUBLIC_serialize(const TPMI_ALG_PUBLIC in, json_object **jso)
3460 {
3461 CHECK_IN_LIST(TPMI_ALG_PUBLIC, in, TPM2_ALG_RSA, TPM2_ALG_KEYEDHASH,
3462 TPM2_ALG_ECC, TPM2_ALG_SYMCIPHER, TPM2_ALG_NULL);
3463 return ifapi_json_TPM2_ALG_ID_serialize(in, jso);
3464 }
3465
3466 /** Serialize a TPMU_PUBLIC_ID to json.
3467 *
3468 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
3469 * @param[in] in the value to be serialized.
3470 * @param[in] selector the type of the public ID.
3471 * @param[out] jso pointer to the json object.
3472 * @retval TSS2_RC_SUCCESS if the function call was a success.
3473 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3474 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_PUBLIC_ID.
3475 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3476 */
3477 TSS2_RC
3478 ifapi_json_TPMU_PUBLIC_ID_serialize(const TPMU_PUBLIC_ID *in, UINT32 selector, json_object **jso)
3479 {
3480 switch (selector) {
3481 case TPM2_ALG_KEYEDHASH:
3482 return ifapi_json_TPM2B_DIGEST_serialize(&in->keyedHash, jso);
3483 case TPM2_ALG_SYMCIPHER:
3484 return ifapi_json_TPM2B_DIGEST_serialize(&in->sym, jso);
3485 case TPM2_ALG_RSA:
3486 return ifapi_json_TPM2B_PUBLIC_KEY_RSA_serialize(&in->rsa, jso);
3487 case TPM2_ALG_ECC:
3488 return ifapi_json_TPMS_ECC_POINT_serialize(&in->ecc, jso);
3489 default:
3490 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
3491 return TSS2_FAPI_RC_BAD_VALUE;
3492 };
3493 return TSS2_RC_SUCCESS;
3494 }
3495
3496 /** Serialize value of type TPMS_KEYEDHASH_PARMS to json.
3497 *
3498 * @param[in] in value to be serialized.
3499 * @param[out] jso pointer to the json object.
3500 * @retval TSS2_RC_SUCCESS if the function call was a success.
3501 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3502 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_KEYEDHASH_PARMS.
3503 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3504 */
3505 TSS2_RC
3506 ifapi_json_TPMS_KEYEDHASH_PARMS_serialize(const TPMS_KEYEDHASH_PARMS *in, json_object **jso)
3507 {
3508 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3509
3510 TSS2_RC r;
3511 json_object *jso2;
3512 if (*jso == NULL)
3513 *jso = json_object_new_object ();
3514 jso2 = NULL;
3515 r = ifapi_json_TPMT_KEYEDHASH_SCHEME_serialize(&in->scheme, &jso2);
3516 return_if_error(r, "Serialize TPMT_KEYEDHASH_SCHEME");
3517
3518 json_object_object_add(*jso, "scheme", jso2);
3519 return TSS2_RC_SUCCESS;
3520 }
3521
3522 /** Serialize value of type TPMS_ASYM_PARMS to json.
3523 *
3524 * @param[in] in value to be serialized.
3525 * @param[out] jso pointer to the json object.
3526 * @retval TSS2_RC_SUCCESS if the function call was a success.
3527 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3528 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_ASYM_PARMS.
3529 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3530 */
3531 TSS2_RC
3532 ifapi_json_TPMS_ASYM_PARMS_serialize(const TPMS_ASYM_PARMS *in, json_object **jso)
3533 {
3534 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3535
3536 TSS2_RC r;
3537 json_object *jso2;
3538 if (*jso == NULL)
3539 *jso = json_object_new_object ();
3540 jso2 = NULL;
3541 r = ifapi_json_TPMT_SYM_DEF_OBJECT_serialize(&in->symmetric, &jso2);
3542 return_if_error(r, "Serialize TPMT_SYM_DEF_OBJECT");
3543
3544 json_object_object_add(*jso, "symmetric", jso2);
3545 jso2 = NULL;
3546 r = ifapi_json_TPMT_ASYM_SCHEME_serialize(&in->scheme, &jso2);
3547 return_if_error(r, "Serialize TPMT_ASYM_SCHEME");
3548
3549 json_object_object_add(*jso, "scheme", jso2);
3550 return TSS2_RC_SUCCESS;
3551 }
3552
3553 /** Serialize value of type TPMS_RSA_PARMS to json.
3554 *
3555 * @param[in] in value to be serialized.
3556 * @param[out] jso pointer to the json object.
3557 * @retval TSS2_RC_SUCCESS if the function call was a success.
3558 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3559 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_RSA_PARMS.
3560 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3561 */
3562 TSS2_RC
3563 ifapi_json_TPMS_RSA_PARMS_serialize(const TPMS_RSA_PARMS *in, json_object **jso)
3564 {
3565 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3566
3567 TSS2_RC r;
3568 json_object *jso2;
3569 if (*jso == NULL)
3570 *jso = json_object_new_object ();
3571 jso2 = NULL;
3572 r = ifapi_json_TPMT_SYM_DEF_OBJECT_serialize(&in->symmetric, &jso2);
3573 return_if_error(r, "Serialize TPMT_SYM_DEF_OBJECT");
3574
3575 json_object_object_add(*jso, "symmetric", jso2);
3576 jso2 = NULL;
3577 r = ifapi_json_TPMT_RSA_SCHEME_serialize(&in->scheme, &jso2);
3578 return_if_error(r, "Serialize TPMT_RSA_SCHEME");
3579
3580 json_object_object_add(*jso, "scheme", jso2);
3581 jso2 = NULL;
3582 r = ifapi_json_TPMI_RSA_KEY_BITS_serialize(in->keyBits, &jso2);
3583 return_if_error(r, "Serialize TPMI_RSA_KEY_BITS");
3584
3585 json_object_object_add(*jso, "keyBits", jso2);
3586 jso2 = NULL;
3587 r = ifapi_json_UINT32_serialize(in->exponent, &jso2);
3588 return_if_error(r, "Serialize UINT32");
3589
3590 json_object_object_add(*jso, "exponent", jso2);
3591 return TSS2_RC_SUCCESS;
3592 }
3593
3594 /** Serialize value of type TPMS_ECC_PARMS to json.
3595 *
3596 * @param[in] in value to be serialized.
3597 * @param[out] jso pointer to the json object.
3598 * @retval TSS2_RC_SUCCESS if the function call was a success.
3599 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3600 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_ECC_PARMS.
3601 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3602 */
3603 TSS2_RC
3604 ifapi_json_TPMS_ECC_PARMS_serialize(const TPMS_ECC_PARMS *in, json_object **jso)
3605 {
3606 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3607
3608 TSS2_RC r;
3609 json_object *jso2;
3610 if (*jso == NULL)
3611 *jso = json_object_new_object ();
3612 jso2 = NULL;
3613 r = ifapi_json_TPMT_SYM_DEF_OBJECT_serialize(&in->symmetric, &jso2);
3614 return_if_error(r, "Serialize TPMT_SYM_DEF_OBJECT");
3615
3616 json_object_object_add(*jso, "symmetric", jso2);
3617 jso2 = NULL;
3618 r = ifapi_json_TPMT_ECC_SCHEME_serialize(&in->scheme, &jso2);
3619 return_if_error(r, "Serialize TPMT_ECC_SCHEME");
3620
3621 json_object_object_add(*jso, "scheme", jso2);
3622 jso2 = NULL;
3623 r = ifapi_json_TPMI_ECC_CURVE_serialize(in->curveID, &jso2);
3624 return_if_error(r, "Serialize TPMI_ECC_CURVE");
3625
3626 json_object_object_add(*jso, "curveID", jso2);
3627 jso2 = NULL;
3628 r = ifapi_json_TPMT_KDF_SCHEME_serialize(&in->kdf, &jso2);
3629 return_if_error(r, "Serialize TPMT_KDF_SCHEME");
3630
3631 json_object_object_add(*jso, "kdf", jso2);
3632 return TSS2_RC_SUCCESS;
3633 }
3634
3635 /** Serialize a TPMU_PUBLIC_PARMS to json.
3636 *
3637 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
3638 * @param[in] in the value to be serialized.
3639 * @param[in] selector the type of the public parameters.
3640 * @param[out] jso pointer to the json object.
3641 * @retval TSS2_RC_SUCCESS if the function call was a success.
3642 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3643 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMU_PUBLIC_PARMS.
3644 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3645 */
3646 TSS2_RC
3647 ifapi_json_TPMU_PUBLIC_PARMS_serialize(const TPMU_PUBLIC_PARMS *in, UINT32 selector, json_object **jso)
3648 {
3649 switch (selector) {
3650 case TPM2_ALG_KEYEDHASH:
3651 return ifapi_json_TPMS_KEYEDHASH_PARMS_serialize(&in->keyedHashDetail, jso);
3652 case TPM2_ALG_SYMCIPHER:
3653 return ifapi_json_TPMS_SYMCIPHER_PARMS_serialize(&in->symDetail, jso);
3654 case TPM2_ALG_RSA:
3655 return ifapi_json_TPMS_RSA_PARMS_serialize(&in->rsaDetail, jso);
3656 case TPM2_ALG_ECC:
3657 return ifapi_json_TPMS_ECC_PARMS_serialize(&in->eccDetail, jso);
3658 default:
3659 LOG_ERROR("\nSelector %"PRIx32 " did not match", selector);
3660 return TSS2_FAPI_RC_BAD_VALUE;
3661 };
3662 return TSS2_RC_SUCCESS;
3663 }
3664
3665 /** Serialize value of type TPMT_PUBLIC to json.
3666 *
3667 * @param[in] in value to be serialized.
3668 * @param[out] jso pointer to the json object.
3669 * @retval TSS2_RC_SUCCESS if the function call was a success.
3670 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3671 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMT_PUBLIC.
3672 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3673 */
3674 TSS2_RC
3675 ifapi_json_TPMT_PUBLIC_serialize(const TPMT_PUBLIC *in, json_object **jso)
3676 {
3677 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3678
3679 TSS2_RC r;
3680 json_object *jso2;
3681 if (*jso == NULL)
3682 *jso = json_object_new_object ();
3683 jso2 = NULL;
3684 r = ifapi_json_TPMI_ALG_PUBLIC_serialize(in->type, &jso2);
3685 return_if_error(r, "Serialize TPMI_ALG_PUBLIC");
3686
3687 json_object_object_add(*jso, "type", jso2);
3688 jso2 = NULL;
3689 r = ifapi_json_TPMI_ALG_HASH_serialize(in->nameAlg, &jso2);
3690 return_if_error(r, "Serialize TPMI_ALG_HASH");
3691
3692 json_object_object_add(*jso, "nameAlg", jso2);
3693 jso2 = NULL;
3694 r = ifapi_json_TPMA_OBJECT_serialize(in->objectAttributes, &jso2);
3695 return_if_error(r, "Serialize TPMA_OBJECT");
3696
3697 json_object_object_add(*jso, "objectAttributes", jso2);
3698 jso2 = NULL;
3699 r = ifapi_json_TPM2B_DIGEST_serialize(&in->authPolicy, &jso2);
3700 return_if_error(r, "Serialize TPM2B_DIGEST");
3701
3702 json_object_object_add(*jso, "authPolicy", jso2);
3703 jso2 = NULL;
3704 r = ifapi_json_TPMU_PUBLIC_PARMS_serialize(&in->parameters, in->type, &jso2);
3705 return_if_error(r,"Serialize TPMU_PUBLIC_PARMS");
3706
3707 json_object_object_add(*jso, "parameters", jso2);
3708 jso2 = NULL;
3709 r = ifapi_json_TPMU_PUBLIC_ID_serialize(&in->unique, in->type, &jso2);
3710 return_if_error(r,"Serialize TPMU_PUBLIC_ID");
3711
3712 json_object_object_add(*jso, "unique", jso2);
3713 return TSS2_RC_SUCCESS;
3714 }
3715
3716 /** Serialize a TPM2B_PUBLIC to json.
3717 *
3718 * @param[in] in value to be serialized.
3719 * @param[out] jso pointer to the json object.
3720 * @retval TSS2_RC_SUCCESS if the function call was a success.
3721 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3722 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_PUBLIC.
3723 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3724 */
3725 TSS2_RC
3726 ifapi_json_TPM2B_PUBLIC_serialize(const TPM2B_PUBLIC *in, json_object **jso)
3727 {
3728 if (*jso == NULL)
3729 *jso = json_object_new_object ();
3730 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3731
3732 json_object *jso2;
3733
3734 jso2 = NULL;
3735 if (ifapi_json_UINT16_serialize(in->size, &jso2))
3736 return TSS2_FAPI_RC_BAD_VALUE;
3737
3738 json_object_object_add(*jso, "size", jso2);
3739
3740 jso2 = NULL;
3741 if (ifapi_json_TPMT_PUBLIC_serialize(&in->publicArea, &jso2))
3742 return TSS2_FAPI_RC_BAD_VALUE;
3743
3744 json_object_object_add(*jso, "publicArea", jso2);
3745
3746 return TSS2_RC_SUCCESS;
3747 }
3748
3749 /** Serialize value of type TPM2B_PRIVATE to json.
3750 *
3751 * @param[in] in value to be serialized.
3752 * @param[out] jso pointer to the json object.
3753 * @retval TSS2_RC_SUCCESS if the function call was a success.
3754 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3755 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_PRIVATE.
3756 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3757 */
3758 TSS2_RC
3759 ifapi_json_TPM2B_PRIVATE_serialize(const TPM2B_PRIVATE *in, json_object **jso)
3760 {
3761 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3762
3763 if (in->size > sizeof(_PRIVATE)) {
3764 LOG_ERROR("Too many bytes for array (%"PRIuPTR" > %"PRIuPTR" = sizeof(_PRIVATE))",
3765 (size_t)in->size, (size_t)sizeof(_PRIVATE));
3766 return TSS2_FAPI_RC_BAD_VALUE;
3767 }
3768 char hex_string[((size_t)in->size)*2+1];
3769
3770 for (size_t i = 0, off = 0; i < in->size; i++, off+=2)
3771 sprintf(&hex_string[off], "%02x", in->buffer[i]);
3772 hex_string[(in->size)*2] = '\0';
3773 *jso = json_object_new_string (hex_string);
3774 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3775
3776 return TSS2_RC_SUCCESS;
3777 }
3778
3779 /** Serialize TPM2_NT to json.
3780 *
3781 * @param[in] in constant to be serialized.
3782 * @param[out] jso pointer to the json object.
3783 * @retval TSS2_RC_SUCCESS if the function call was a success.
3784 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3785 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPM2_NT.
3786 */
3787 TSS2_RC
3788 ifapi_json_TPM2_NT_serialize(const TPM2_NT in, json_object **jso)
3789 {
3790 static const struct { TPM2_NT in; char *name; } tab[] = {
3791 { TPM2_NT_ORDINARY, "ORDINARY" },
3792 { TPM2_NT_COUNTER, "COUNTER" },
3793 { TPM2_NT_BITS, "BITS" },
3794 { TPM2_NT_EXTEND, "EXTEND" },
3795 { TPM2_NT_PIN_FAIL, "PIN_FAIL" },
3796 { TPM2_NT_PIN_PASS, "PIN_PASS" },
3797 };
3798
3799 for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
3800 if (tab[i].in == in) {
3801 *jso = json_object_new_string(tab[i].name);
3802 check_oom(*jso);
3803 return TSS2_RC_SUCCESS;
3804 }
3805 }
3806 return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
3807 }
3808
3809 /** Serialize a TPMA_NV to json.
3810 *
3811 * This function expects the Bitfield to be encoded as unsigned int in host-endianess.
3812 *
3813 * @param[in] in value to be serialized.
3814 * @param[out] jso pointer to the json object.
3815 * @retval TSS2_RC_SUCCESS if the function call was a success.
3816 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3817 * @retval TSS2_FAPI_RC_BAD_VALUE if the constant is not of type TPMA_NV.
3818 */
3819 TSS2_RC
3820 ifapi_json_TPMA_NV_serialize(const TPMA_NV in, json_object **jso)
3821 {
3822 struct { TPMA_NV in; char *name; } tab[] = {
3823 { TPMA_NV_PPWRITE, "PPWRITE" },
3824 { TPMA_NV_OWNERWRITE, "OWNERWRITE" },
3825 { TPMA_NV_AUTHWRITE, "AUTHWRITE" },
3826 { TPMA_NV_POLICYWRITE, "POLICYWRITE" },
3827 { TPMA_NV_POLICY_DELETE, "POLICY_DELETE" },
3828 { TPMA_NV_WRITELOCKED, "WRITELOCKED" },
3829 { TPMA_NV_WRITEALL, "WRITEALL" },
3830 { TPMA_NV_WRITEDEFINE, "WRITEDEFINE" },
3831 { TPMA_NV_WRITE_STCLEAR, "WRITE_STCLEAR" },
3832 { TPMA_NV_GLOBALLOCK, "GLOBALLOCK" },
3833 { TPMA_NV_PPREAD, "PPREAD" },
3834 { TPMA_NV_OWNERREAD, "OWNERREAD" },
3835 { TPMA_NV_AUTHREAD, "AUTHREAD" },
3836 { TPMA_NV_POLICYREAD, "POLICYREAD" },
3837 { TPMA_NV_NO_DA, "NO_DA" },
3838 { TPMA_NV_ORDERLY, "ORDERLY" },
3839 { TPMA_NV_CLEAR_STCLEAR, "CLEAR_STCLEAR" },
3840 { TPMA_NV_READLOCKED, "READLOCKED" },
3841 { TPMA_NV_WRITTEN, "WRITTEN" },
3842 { TPMA_NV_PLATFORMCREATE, "PLATFORMCREATE" },
3843 { TPMA_NV_READ_STCLEAR, "READ_STCLEAR" },
3844 };
3845
3846 UINT32 input;
3847 input = (UINT32) in;
3848 json_object *jso_bit;
3849 if (*jso == NULL) {
3850 *jso = json_object_new_object();
3851 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3852 }
3853 size_t n = sizeof(tab) / sizeof(tab[0]);
3854 size_t i;
3855 for (i = 0; i < n; i++) {
3856 if (tab[i].in & input)
3857 jso_bit = json_object_new_int(1);
3858 else
3859 jso_bit = json_object_new_int(0);
3860 return_if_null(jso_bit, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3861
3862 json_object_object_add(*jso, tab[i].name, jso_bit);
3863 }
3864 TPM2_NT input2 = (TPMA_NV_TPM2_NT_MASK & input)>>4;
3865 json_object *jso2 = NULL;
3866 TSS2_RC r = ifapi_json_TPM2_NT_serialize(input2, &jso2);
3867 return_if_error(r, "Bad value");
3868
3869 json_object_object_add(*jso, "TPM2_NT", jso2);
3870
3871 return TSS2_RC_SUCCESS;
3872 }
3873
3874 /** Serialize value of type TPMS_NV_PUBLIC to json.
3875 *
3876 * @param[in] in value to be serialized.
3877 * @param[out] jso pointer to the json object.
3878 * @retval TSS2_RC_SUCCESS if the function call was a success.
3879 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3880 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_NV_PUBLIC.
3881 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3882 */
3883 TSS2_RC
3884 ifapi_json_TPMS_NV_PUBLIC_serialize(const TPMS_NV_PUBLIC *in, json_object **jso)
3885 {
3886 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3887
3888 TSS2_RC r;
3889 json_object *jso2;
3890 if (*jso == NULL)
3891 *jso = json_object_new_object ();
3892 jso2 = NULL;
3893 r = ifapi_json_TPMI_RH_NV_INDEX_serialize(in->nvIndex, &jso2);
3894 return_if_error(r, "Serialize TPMI_RH_NV_INDEX");
3895
3896 json_object_object_add(*jso, "nvIndex", jso2);
3897 jso2 = NULL;
3898 r = ifapi_json_TPMI_ALG_HASH_serialize(in->nameAlg, &jso2);
3899 return_if_error(r, "Serialize TPMI_ALG_HASH");
3900
3901 json_object_object_add(*jso, "nameAlg", jso2);
3902 jso2 = NULL;
3903 r = ifapi_json_TPMA_NV_serialize(in->attributes, &jso2);
3904 return_if_error(r, "Serialize TPMA_NV");
3905
3906 json_object_object_add(*jso, "attributes", jso2);
3907 jso2 = NULL;
3908 r = ifapi_json_TPM2B_DIGEST_serialize(&in->authPolicy, &jso2);
3909 return_if_error(r, "Serialize TPM2B_DIGEST");
3910
3911 json_object_object_add(*jso, "authPolicy", jso2);
3912 jso2 = NULL;
3913 r = ifapi_json_UINT16_serialize(in->dataSize, &jso2);
3914 return_if_error(r, "Serialize UINT16");
3915
3916 json_object_object_add(*jso, "dataSize", jso2);
3917 return TSS2_RC_SUCCESS;
3918 }
3919
3920 /** Serialize a TPM2B_NV_PUBLIC to json.
3921 *
3922 * @param[in] in value to be serialized.
3923 * @param[out] jso pointer to the json object.
3924 * @retval TSS2_RC_SUCCESS if the function call was a success.
3925 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3926 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_NV_PUBLIC.
3927 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3928 */
3929 TSS2_RC
3930 ifapi_json_TPM2B_NV_PUBLIC_serialize(const TPM2B_NV_PUBLIC *in, json_object **jso)
3931 {
3932 if (*jso == NULL)
3933 *jso = json_object_new_object ();
3934 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
3935
3936 json_object *jso2;
3937
3938 jso2 = NULL;
3939 if (ifapi_json_UINT16_serialize(in->size, &jso2))
3940 return TSS2_FAPI_RC_BAD_VALUE;
3941
3942 json_object_object_add(*jso, "size", jso2);
3943
3944 jso2 = NULL;
3945 if (ifapi_json_TPMS_NV_PUBLIC_serialize(&in->nvPublic, &jso2))
3946 return TSS2_FAPI_RC_BAD_VALUE;
3947
3948 json_object_object_add(*jso, "nvPublic", jso2);
3949
3950 return TSS2_RC_SUCCESS;
3951 }
3952
3953 /** Serialize value of type TPMS_CREATION_DATA to json.
3954 *
3955 * @param[in] in value to be serialized.
3956 * @param[out] jso pointer to the json object.
3957 * @retval TSS2_RC_SUCCESS if the function call was a success.
3958 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
3959 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPMS_CREATION_DATA.
3960 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
3961 */
3962 TSS2_RC
3963 ifapi_json_TPMS_CREATION_DATA_serialize(const TPMS_CREATION_DATA *in, json_object **jso)
3964 {
3965 return_if_null(in, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
3966
3967 TSS2_RC r;
3968 json_object *jso2;
3969 if (*jso == NULL)
3970 *jso = json_object_new_object ();
3971 jso2 = NULL;
3972 r = ifapi_json_TPML_PCR_SELECTION_serialize(&in->pcrSelect, &jso2);
3973 return_if_error(r, "Serialize TPML_PCR_SELECTION");
3974
3975 json_object_object_add(*jso, "pcrSelect", jso2);
3976 jso2 = NULL;
3977 r = ifapi_json_TPM2B_DIGEST_serialize(&in->pcrDigest, &jso2);
3978 return_if_error(r, "Serialize TPM2B_DIGEST");
3979
3980 json_object_object_add(*jso, "pcrDigest", jso2);
3981 jso2 = NULL;
3982 r = ifapi_json_TPMA_LOCALITY_serialize(in->locality, &jso2);
3983 return_if_error(r, "Serialize TPMA_LOCALITY");
3984
3985 json_object_object_add(*jso, "locality", jso2);
3986 jso2 = NULL;
3987 r = ifapi_json_TPM2_ALG_ID_serialize(in->parentNameAlg, &jso2);
3988 return_if_error(r, "Serialize TPM2_ALG_ID");
3989
3990 json_object_object_add(*jso, "parentNameAlg", jso2);
3991 jso2 = NULL;
3992 r = ifapi_json_TPM2B_NAME_serialize(&in->parentName, &jso2);
3993 return_if_error(r, "Serialize TPM2B_NAME");
3994
3995 json_object_object_add(*jso, "parentName", jso2);
3996 jso2 = NULL;
3997 r = ifapi_json_TPM2B_NAME_serialize(&in->parentQualifiedName, &jso2);
3998 return_if_error(r, "Serialize TPM2B_NAME");
3999
4000 json_object_object_add(*jso, "parentQualifiedName", jso2);
4001 jso2 = NULL;
4002 r = ifapi_json_TPM2B_DATA_serialize(&in->outsideInfo, &jso2);
4003 return_if_error(r, "Serialize TPM2B_DATA");
4004
4005 json_object_object_add(*jso, "outsideInfo", jso2);
4006 return TSS2_RC_SUCCESS;
4007 }
4008
4009 /** Serialize a TPM2B_CREATION_DATA to json.
4010 *
4011 * @param[in] in value to be serialized.
4012 * @param[out] jso pointer to the json object.
4013 * @retval TSS2_RC_SUCCESS if the function call was a success.
4014 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory.
4015 * @retval TSS2_FAPI_RC_BAD_VALUE if the value is not of type TPM2B_CREATION_DATA.
4016 */
4017 TSS2_RC
4018 ifapi_json_TPM2B_CREATION_DATA_serialize(const TPM2B_CREATION_DATA *in, json_object **jso)
4019 {
4020 if (*jso == NULL)
4021 *jso = json_object_new_object ();
4022 return_if_null(*jso, "Out of memory.", TSS2_FAPI_RC_MEMORY);
4023
4024 json_object *jso2;
4025
4026 jso2 = NULL;
4027 if (ifapi_json_UINT16_serialize(in->size, &jso2))
4028 return TSS2_FAPI_RC_BAD_VALUE;
4029
4030 json_object_object_add(*jso, "size", jso2);
4031
4032 jso2 = NULL;
4033 if (ifapi_json_TPMS_CREATION_DATA_serialize(&in->creationData, &jso2))
4034 return TSS2_FAPI_RC_BAD_VALUE;
4035
4036 json_object_object_add(*jso, "creationData", jso2);
4037
4038 return TSS2_RC_SUCCESS;
4039 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5 #ifndef FAPI_TPM_JSON_SERIALIZE_H
6 #define FAPI_TPM_JSON_SERIALIZE_H
7
8 #include <stdbool.h>
9 #include <json-c/json.h>
10 #include <json-c/json_util.h>
11
12 #include "tss2_tpm2_types.h"
13 #include "fapi_int.h"
14
15 #define YES 1
16 #define NO 0
17
18 TSS2_RC
19 ifapi_json_TPM2_HANDLE_serialize(const TPM2_HANDLE in, json_object **jso);
20
21 TSS2_RC
22 ifapi_json_UINT16_serialize(const UINT16 in, json_object **jso);
23
24 TSS2_RC
25 ifapi_json_UINT32_serialize(const UINT32 in, json_object **jso);
26
27 TSS2_RC
28 ifapi_json_INT32_serialize(const INT32 in, json_object **jso);
29
30 TSS2_RC
31 ifapi_json_UINT64_serialize(const UINT64 in, json_object **jso);
32
33 TSS2_RC
34 ifapi_json_TPM2_GENERATED_serialize(const TPM2_GENERATED in, json_object **jso);
35
36 TSS2_RC
37 ifapi_json_TPM2_ALG_ID_serialize(const TPM2_ALG_ID in, json_object **jso);
38
39 TSS2_RC
40 ifapi_json_TPM2_ECC_CURVE_serialize(const TPM2_ECC_CURVE in, json_object **jso);
41
42 TSS2_RC
43 ifapi_json_TPM2_CC_serialize(const TPM2_CC in, json_object **jso);
44
45 TSS2_RC
46 ifapi_json_TPM2_EO_serialize(const TPM2_EO in, json_object **jso);
47
48 TSS2_RC
49 ifapi_json_TPM2_ST_serialize(const TPM2_ST in, json_object **jso);
50
51 TSS2_RC
52 ifapi_json_TPM2_CAP_serialize(const TPM2_CAP in, json_object **jso);
53
54 TSS2_RC
55 ifapi_json_TPM2_PT_serialize(const TPM2_PT in, json_object **jso);
56
57 TSS2_RC
58 ifapi_json_TPM2_PT_PCR_serialize(const TPM2_PT_PCR in, json_object **jso);
59
60 TSS2_RC
61 ifapi_json_TPMA_ALGORITHM_serialize(const TPMA_ALGORITHM in, json_object **jso);
62
63 TSS2_RC
64 ifapi_json_TPMA_OBJECT_serialize(const TPMA_OBJECT in, json_object **jso);
65
66 TSS2_RC
67 ifapi_json_TPMA_LOCALITY_serialize(const TPMA_LOCALITY in, json_object **jso);
68
69 TSS2_RC
70 ifapi_json_TPMA_CC_serialize(const TPMA_CC in, json_object **jso);
71
72 TSS2_RC
73 ifapi_json_TPMI_YES_NO_serialize(const TPMI_YES_NO in, json_object **jso);
74
75 TSS2_RC
76 ifapi_json_TPMI_RH_HIERARCHY_serialize(const TPMI_RH_HIERARCHY in,
77 json_object **jso);
78
79 TSS2_RC
80 ifapi_json_TPMI_RH_NV_INDEX_serialize(const TPMI_RH_NV_INDEX in,
81 json_object **jso);
82
83 TSS2_RC
84 ifapi_json_TPMI_ALG_HASH_serialize(const TPMI_ALG_HASH in, json_object **jso);
85
86 TSS2_RC
87 ifapi_json_TPMI_ALG_SYM_OBJECT_serialize(const TPMI_ALG_SYM_OBJECT in,
88 json_object **jso);
89
90 TSS2_RC
91 ifapi_json_TPMI_ALG_SYM_MODE_serialize(const TPMI_ALG_SYM_MODE in,
92 json_object **jso);
93
94 TSS2_RC
95 ifapi_json_TPMI_ALG_KDF_serialize(const TPMI_ALG_KDF in, json_object **jso);
96
97 TSS2_RC
98 ifapi_json_TPMI_ALG_SIG_SCHEME_serialize(const TPMI_ALG_SIG_SCHEME in,
99 json_object **jso);
100
101 TSS2_RC
102 ifapi_json_TPMS_EMPTY_serialize(const TPMS_EMPTY *in, json_object **jso);
103
104 TSS2_RC
105 ifapi_json_TPMU_HA_serialize(const TPMU_HA *in, UINT32 selector,
106 json_object **jso);
107
108 TSS2_RC
109 ifapi_json_TPMT_HA_serialize(const TPMT_HA *in, json_object **jso);
110
111 TSS2_RC
112 ifapi_json_TPM2B_DIGEST_serialize(const TPM2B_DIGEST *in, json_object **jso);
113
114 TSS2_RC
115 ifapi_json_TPM2B_DATA_serialize(const TPM2B_DATA *in, json_object **jso);
116
117 TSS2_RC
118 ifapi_json_TPM2B_NONCE_serialize(const TPM2B_NONCE *in, json_object **jso);
119
120 TSS2_RC
121 ifapi_json_TPM2B_OPERAND_serialize(const TPM2B_OPERAND *in, json_object **jso);
122
123 TSS2_RC
124 ifapi_json_TPM2B_EVENT_serialize(const TPM2B_EVENT *in, json_object **jso);
125
126 TSS2_RC
127 ifapi_json_TPM2B_MAX_NV_BUFFER_serialize(const TPM2B_MAX_NV_BUFFER *in,
128 json_object **jso);
129
130 TSS2_RC
131 ifapi_json_TPM2B_NAME_serialize(const TPM2B_NAME *in, json_object **jso);
132
133 TSS2_RC
134 ifapi_json_TPMS_PCR_SELECT_serialize(const TPMS_PCR_SELECT *in,
135 json_object **jso);
136
137 TSS2_RC
138 ifapi_json_TPMS_PCR_SELECTION_serialize(const TPMS_PCR_SELECTION *in,
139 json_object **jso);
140
141 TSS2_RC
142 ifapi_json_TPMT_TK_CREATION_serialize(const TPMT_TK_CREATION *in,
143 json_object **jso);
144
145 TSS2_RC
146 ifapi_json_TPMS_ALG_PROPERTY_serialize(const TPMS_ALG_PROPERTY *in,
147 json_object **jso);
148
149 TSS2_RC
150 ifapi_json_TPMS_TAGGED_PROPERTY_serialize(const TPMS_TAGGED_PROPERTY *in,
151 json_object **jso);
152
153 TSS2_RC
154 ifapi_json_TPMS_TAGGED_PCR_SELECT_serialize(const TPMS_TAGGED_PCR_SELECT *in,
155 json_object **jso);
156
157 TSS2_RC
158 ifapi_json_TPML_CC_serialize(const TPML_CC *in, json_object **jso);
159
160 TSS2_RC
161 ifapi_json_TPML_CCA_serialize(const TPML_CCA *in, json_object **jso);
162
163 TSS2_RC
164 ifapi_json_TPML_HANDLE_serialize(const TPML_HANDLE *in, json_object **jso);
165
166 TSS2_RC
167 ifapi_json_TPML_DIGEST_VALUES_serialize(const TPML_DIGEST_VALUES *in,
168 json_object **jso);
169
170 TSS2_RC
171 ifapi_json_TPML_PCR_SELECTION_serialize(const TPML_PCR_SELECTION *in,
172 json_object **jso);
173
174 TSS2_RC
175 ifapi_json_TPML_ALG_PROPERTY_serialize(const TPML_ALG_PROPERTY *in,
176 json_object **jso);
177
178 TSS2_RC
179 ifapi_json_TPML_TAGGED_TPM_PROPERTY_serialize(const TPML_TAGGED_TPM_PROPERTY
180 *in, json_object **jso);
181
182 TSS2_RC
183 ifapi_json_TPML_TAGGED_PCR_PROPERTY_serialize(const TPML_TAGGED_PCR_PROPERTY
184 *in, json_object **jso);
185
186 TSS2_RC
187 ifapi_json_TPML_ECC_CURVE_serialize(const TPML_ECC_CURVE *in,
188 json_object **jso);
189
190 TSS2_RC
191 ifapi_json_TPMU_CAPABILITIES_serialize(const TPMU_CAPABILITIES *in,
192 UINT32 selector, json_object **jso);
193
194 TSS2_RC
195 ifapi_json_TPMS_CAPABILITY_DATA_serialize(const TPMS_CAPABILITY_DATA *in,
196 json_object **jso);
197
198 TSS2_RC
199 ifapi_json_TPMS_CLOCK_INFO_serialize(const TPMS_CLOCK_INFO *in,
200 json_object **jso);
201
202 TSS2_RC
203 ifapi_json_TPMS_TIME_INFO_serialize(const TPMS_TIME_INFO *in,
204 json_object **jso);
205
206 TSS2_RC
207 ifapi_json_TPMS_TIME_ATTEST_INFO_serialize(const TPMS_TIME_ATTEST_INFO *in,
208 json_object **jso);
209
210 TSS2_RC
211 ifapi_json_TPMS_CERTIFY_INFO_serialize(const TPMS_CERTIFY_INFO *in,
212 json_object **jso);
213
214 TSS2_RC
215 ifapi_json_TPMS_QUOTE_INFO_serialize(const TPMS_QUOTE_INFO *in,
216 json_object **jso);
217
218 TSS2_RC
219 ifapi_json_TPMS_COMMAND_AUDIT_INFO_serialize(const TPMS_COMMAND_AUDIT_INFO *in,
220 json_object **jso);
221
222 TSS2_RC
223 ifapi_json_TPMS_SESSION_AUDIT_INFO_serialize(const TPMS_SESSION_AUDIT_INFO *in,
224 json_object **jso);
225
226 TSS2_RC
227 ifapi_json_TPMS_CREATION_INFO_serialize(const TPMS_CREATION_INFO *in,
228 json_object **jso);
229
230 TSS2_RC
231 ifapi_json_TPMS_NV_CERTIFY_INFO_serialize(const TPMS_NV_CERTIFY_INFO *in,
232 json_object **jso);
233
234 TSS2_RC
235 ifapi_json_TPMI_ST_ATTEST_serialize(const TPMI_ST_ATTEST in, json_object **jso);
236
237 TSS2_RC
238 ifapi_json_TPMU_ATTEST_serialize(const TPMU_ATTEST *in, UINT32 selector,
239 json_object **jso);
240
241 TSS2_RC
242 ifapi_json_TPMS_ATTEST_serialize(const TPMS_ATTEST *in, json_object **jso);
243
244 TSS2_RC
245 ifapi_json_TPMI_AES_KEY_BITS_serialize(const TPMI_AES_KEY_BITS in,
246 json_object **jso);
247
248 TSS2_RC
249 ifapi_json_TPMU_SYM_KEY_BITS_serialize(const TPMU_SYM_KEY_BITS *in,
250 UINT32 selector, json_object **jso);
251
252 TSS2_RC
253 ifapi_json_TPMU_SYM_MODE_serialize(const TPMU_SYM_MODE *in, UINT32 selector,
254 json_object **jso);
255
256 TSS2_RC
257 ifapi_json_TPMT_SYM_DEF_OBJECT_serialize(const TPMT_SYM_DEF_OBJECT *in,
258 json_object **jso);
259
260 TSS2_RC
261 ifapi_json_TPMS_SYMCIPHER_PARMS_serialize(const TPMS_SYMCIPHER_PARMS *in,
262 json_object **jso);
263
264 TSS2_RC
265 ifapi_json_TPMS_SCHEME_HASH_serialize(const TPMS_SCHEME_HASH *in,
266 json_object **jso);
267
268 TSS2_RC
269 ifapi_json_TPMS_SCHEME_ECDAA_serialize(const TPMS_SCHEME_ECDAA *in,
270 json_object **jso);
271
272 TSS2_RC
273 ifapi_json_TPMI_ALG_KEYEDHASH_SCHEME_serialize(const TPMI_ALG_KEYEDHASH_SCHEME
274 in, json_object **jso);
275
276 TSS2_RC
277 ifapi_json_TPMS_SCHEME_HMAC_serialize(const TPMS_SCHEME_HMAC *in,
278 json_object **jso);
279
280 TSS2_RC
281 ifapi_json_TPMS_SCHEME_XOR_serialize(const TPMS_SCHEME_XOR *in,
282 json_object **jso);
283
284 TSS2_RC
285 ifapi_json_TPMU_SCHEME_KEYEDHASH_serialize(const TPMU_SCHEME_KEYEDHASH *in,
286 UINT32 selector, json_object **jso);
287
288 TSS2_RC
289 ifapi_json_TPMT_KEYEDHASH_SCHEME_serialize(const TPMT_KEYEDHASH_SCHEME *in,
290 json_object **jso);
291
292 TSS2_RC
293 ifapi_json_TPMS_SIG_SCHEME_RSASSA_serialize(const TPMS_SIG_SCHEME_RSASSA *in,
294 json_object **jso);
295
296 TSS2_RC
297 ifapi_json_TPMS_SIG_SCHEME_RSAPSS_serialize(const TPMS_SIG_SCHEME_RSAPSS *in,
298 json_object **jso);
299
300 TSS2_RC
301 ifapi_json_TPMS_SIG_SCHEME_ECDSA_serialize(const TPMS_SIG_SCHEME_ECDSA *in,
302 json_object **jso);
303
304 TSS2_RC
305 ifapi_json_TPMS_SIG_SCHEME_SM2_serialize(const TPMS_SIG_SCHEME_SM2 *in,
306 json_object **jso);
307
308 TSS2_RC
309 ifapi_json_TPMS_SIG_SCHEME_ECSCHNORR_serialize(const TPMS_SIG_SCHEME_ECSCHNORR
310 *in, json_object **jso);
311
312 TSS2_RC
313 ifapi_json_TPMS_SIG_SCHEME_ECDAA_serialize(const TPMS_SIG_SCHEME_ECDAA *in,
314 json_object **jso);
315
316 TSS2_RC
317 ifapi_json_TPMU_SIG_SCHEME_serialize(const TPMU_SIG_SCHEME *in, UINT32 selector,
318 json_object **jso);
319
320 TSS2_RC
321 ifapi_json_TPMT_SIG_SCHEME_serialize(const TPMT_SIG_SCHEME *in,
322 json_object **jso);
323
324 TSS2_RC
325 ifapi_json_TPMS_ENC_SCHEME_OAEP_serialize(const TPMS_ENC_SCHEME_OAEP *in,
326 json_object **jso);
327
328 TSS2_RC
329 ifapi_json_TPMS_ENC_SCHEME_RSAES_serialize(const TPMS_ENC_SCHEME_RSAES *in,
330 json_object **jso);
331
332 TSS2_RC
333 ifapi_json_TPMS_KEY_SCHEME_ECDH_serialize(const TPMS_KEY_SCHEME_ECDH *in,
334 json_object **jso);
335
336 TSS2_RC
337 ifapi_json_TPMS_SCHEME_MGF1_serialize(const TPMS_SCHEME_MGF1 *in,
338 json_object **jso);
339
340 TSS2_RC
341 ifapi_json_TPMS_SCHEME_KDF1_SP800_56A_serialize(const TPMS_SCHEME_KDF1_SP800_56A
342 *in, json_object **jso);
343
344 TSS2_RC
345 ifapi_json_TPMS_SCHEME_KDF1_SP800_108_serialize(const TPMS_SCHEME_KDF1_SP800_108
346 *in, json_object **jso);
347
348 TSS2_RC
349 ifapi_json_TPMU_KDF_SCHEME_serialize(const TPMU_KDF_SCHEME *in, UINT32 selector,
350 json_object **jso);
351
352 TSS2_RC
353 ifapi_json_TPMT_KDF_SCHEME_serialize(const TPMT_KDF_SCHEME *in,
354 json_object **jso);
355
356 TSS2_RC
357 ifapi_json_TPMI_ALG_ASYM_SCHEME_serialize(const TPMI_ALG_ASYM_SCHEME in,
358 json_object **jso);
359
360 TSS2_RC
361 ifapi_json_TPMU_ASYM_SCHEME_serialize(const TPMU_ASYM_SCHEME *in,
362 UINT32 selector, json_object **jso);
363
364 TSS2_RC
365 ifapi_json_TPMT_ASYM_SCHEME_serialize(const TPMT_ASYM_SCHEME *in,
366 json_object **jso);
367
368 TSS2_RC
369 ifapi_json_TPMI_ALG_RSA_SCHEME_serialize(const TPMI_ALG_RSA_SCHEME in,
370 json_object **jso);
371
372 TSS2_RC
373 ifapi_json_TPMT_RSA_SCHEME_serialize(const TPMT_RSA_SCHEME *in,
374 json_object **jso);
375
376 TSS2_RC
377 ifapi_json_TPM2B_PUBLIC_KEY_RSA_serialize(const TPM2B_PUBLIC_KEY_RSA *in,
378 json_object **jso);
379
380 TSS2_RC
381 ifapi_json_TPMI_RSA_KEY_BITS_serialize(const TPMI_RSA_KEY_BITS in,
382 json_object **jso);
383
384 TSS2_RC
385 ifapi_json_TPM2B_ECC_PARAMETER_serialize(const TPM2B_ECC_PARAMETER *in,
386 json_object **jso);
387
388 TSS2_RC
389 ifapi_json_TPMS_ECC_POINT_serialize(const TPMS_ECC_POINT *in,
390 json_object **jso);
391
392 TSS2_RC
393 ifapi_json_TPMI_ALG_ECC_SCHEME_serialize(const TPMI_ALG_ECC_SCHEME in,
394 json_object **jso);
395
396 TSS2_RC
397 ifapi_json_TPMI_ECC_CURVE_serialize(const TPMI_ECC_CURVE in, json_object **jso);
398
399 TSS2_RC
400 ifapi_json_TPMT_ECC_SCHEME_serialize(const TPMT_ECC_SCHEME *in,
401 json_object **jso);
402
403 TSS2_RC
404 ifapi_json_TPMS_SIGNATURE_RSA_serialize(const TPMS_SIGNATURE_RSA *in,
405 json_object **jso);
406
407 TSS2_RC
408 ifapi_json_TPMS_SIGNATURE_RSASSA_serialize(const TPMS_SIGNATURE_RSASSA *in,
409 json_object **jso);
410
411 TSS2_RC
412 ifapi_json_TPMS_SIGNATURE_RSAPSS_serialize(const TPMS_SIGNATURE_RSAPSS *in,
413 json_object **jso);
414
415 TSS2_RC
416 ifapi_json_TPMS_SIGNATURE_ECC_serialize(const TPMS_SIGNATURE_ECC *in,
417 json_object **jso);
418
419 TSS2_RC
420 ifapi_json_TPMS_SIGNATURE_ECDSA_serialize(const TPMS_SIGNATURE_ECDSA *in,
421 json_object **jso);
422
423 TSS2_RC
424 ifapi_json_TPMS_SIGNATURE_ECDAA_serialize(const TPMS_SIGNATURE_ECDAA *in,
425 json_object **jso);
426
427 TSS2_RC
428 ifapi_json_TPMS_SIGNATURE_SM2_serialize(const TPMS_SIGNATURE_SM2 *in,
429 json_object **jso);
430
431 TSS2_RC
432 ifapi_json_TPMS_SIGNATURE_ECSCHNORR_serialize(const TPMS_SIGNATURE_ECSCHNORR
433 *in, json_object **jso);
434
435 TSS2_RC
436 ifapi_json_TPMU_SIGNATURE_serialize(const TPMU_SIGNATURE *in, UINT32 selector,
437 json_object **jso);
438
439 TSS2_RC
440 ifapi_json_TPMT_SIGNATURE_serialize(const TPMT_SIGNATURE *in,
441 json_object **jso);
442
443 TSS2_RC
444 ifapi_json_TPM2B_ENCRYPTED_SECRET_serialize(const TPM2B_ENCRYPTED_SECRET *in,
445 json_object **jso);
446
447 TSS2_RC
448 ifapi_json_TPMI_ALG_PUBLIC_serialize(const TPMI_ALG_PUBLIC in,
449 json_object **jso);
450
451 TSS2_RC
452 ifapi_json_TPMU_PUBLIC_ID_serialize(const TPMU_PUBLIC_ID *in, UINT32 selector,
453 json_object **jso);
454
455 TSS2_RC
456 ifapi_json_TPMS_KEYEDHASH_PARMS_serialize(const TPMS_KEYEDHASH_PARMS *in,
457 json_object **jso);
458
459 TSS2_RC
460 ifapi_json_TPMS_ASYM_PARMS_serialize(const TPMS_ASYM_PARMS *in,
461 json_object **jso);
462
463 TSS2_RC
464 ifapi_json_TPMS_RSA_PARMS_serialize(const TPMS_RSA_PARMS *in,
465 json_object **jso);
466
467 TSS2_RC
468 ifapi_json_TPMS_ECC_PARMS_serialize(const TPMS_ECC_PARMS *in,
469 json_object **jso);
470
471 TSS2_RC
472 ifapi_json_TPMU_PUBLIC_PARMS_serialize(const TPMU_PUBLIC_PARMS *in,
473 UINT32 selector, json_object **jso);
474
475 TSS2_RC
476 ifapi_json_TPMT_PUBLIC_serialize(const TPMT_PUBLIC *in, json_object **jso);
477
478 TSS2_RC
479 ifapi_json_TPM2B_PUBLIC_serialize(const TPM2B_PUBLIC *in, json_object **jso);
480
481 TSS2_RC
482 ifapi_json_TPM2B_PRIVATE_serialize(const TPM2B_PRIVATE *in, json_object **jso);
483
484 TSS2_RC
485 ifapi_json_TPM2_NT_serialize(const TPM2_NT in, json_object **jso);
486
487 TSS2_RC
488 ifapi_json_TPMA_NV_serialize(const TPMA_NV in, json_object **jso);
489
490 TSS2_RC
491 ifapi_json_TPMS_NV_PUBLIC_serialize(const TPMS_NV_PUBLIC *in,
492 json_object **jso);
493
494 TSS2_RC
495 ifapi_json_TPM2B_NV_PUBLIC_serialize(const TPM2B_NV_PUBLIC *in,
496 json_object **jso);
497
498 TSS2_RC
499 ifapi_json_TPMS_CREATION_DATA_serialize(const TPMS_CREATION_DATA *in,
500 json_object **jso);
501
502 TSS2_RC
503 ifapi_json_TPM2B_CREATION_DATA_serialize(const TPM2B_CREATION_DATA *in,
504 json_object **jso);
505
506 #endif /* FAPI_TPM_JSON_SERIALIZE_H */
702702 /**
703703 * The default system code handler. This handles codes
704704 * from the RM (itself and simulated tpm responses), the marshaling
705 * library (mu), and the tcti layers.
705 * library (mu), the tcti layers, sapi, esys and fapi.
706706 * @param rc
707707 * The rc to decode.
708708 * @return
709709 * An error string.
710710 */
711711 static const char *
712 sys_err_handler (TSS2_RC rc)
712 tss_err_handler (TSS2_RC rc)
713713 {
714714 /*
715715 * subtract 1 from the error number
766766 /* 21 - TSS2_BASE_RC_NOT_SUPPORTED */
767767 "Functionality not supported",
768768 /* 22 - TSS2_BASE_RC_BAD_TCTI_STRUCTURE */
769 "TCTI context is bad"
769 "TCTI context is bad",
770 /* 23 - TSS2_BASE_RC_MEMORY */
771 "Failed to allocate memory",
772 /* 24 - TSS2_BASE_RC_BAD_TR */
773 "The ESYS_TR resource object is bad",
774 /* 25 - TSS2_BASE_RC_MULTIPLE_DECRYPT_SESSIONS */
775 "Multiple sessions were marked with attribute decrypt",
776 /* 26 - TSS2_BASE_RC_MULTIPLE_ENCRYPT_SESSIONS */
777 "Multiple sessions were marked with attribute encrypt",
778 /* 27 - TSS2_BASE_RC_RSP_AUTH_FAILED */
779 "Authorizing the TPM response failed",
780 /* 28 - TSS2_BASE_RC_NO_CONFIG */
781 "No config is available",
782 /* 29 - TSS2_BASE_RC_BAD_PATH */
783 "The provided path is bad",
784 /* 30 - TSS2_BASE_RC_NOT_DELETABLE */
785 "The object is not deletable",
786 /* 31 - TSS2_BASE_RC_PATH_ALREADY_EXISTS */
787 "The provided path already exists",
788 /* 32 - TSS2_BASE_RC_KEY_NOT_FOUND */
789 "The key was not found",
790 /* 33 - TSS2_BASE_RC_SIGNATURE_VERIFICATION_FAILED */
791 "Signature verification failed",
792 /* 34 - TSS2_BASE_RC_HASH_MISMATCH */
793 "Hashes mismatch",
794 /* 35 - TSS2_BASE_RC_KEY_NOT_DUPLICABLE */
795 "Key is not duplicatable",
796 /* 36 - TSS2_BASE_RC_PATH_NOT_FOUND */
797 "The path was not found",
798 /* 37 - TSS2_BASE_RC_NO_CERT */
799 "No certificate",
800 /* 38 - TSS2_BASE_RC_NO_PCR */
801 "No PCR",
802 /* 39 - TSS2_BASE_RC_PCR_NOT_RESETTABLE */
803 "PCR not resettable",
804 /* 40 - TSS2_BASE_RC_BAD_TEMPLATE */
805 "The template is bad",
806 /* 41 - TSS2_BASE_RC_AUTHORIZATION_FAILED */
807 "Authorization failed",
808 /* 42 - TSS2_BASE_RC_AUTHORIZATION_UNKNOWN */
809 "Authorization is unknown",
810 /* 43 - TSS2_BASE_RC_NV_NOT_READABLE */
811 "NV is not readable",
812 /* 44 - TSS2_BASE_RC_NV_TOO_SMALL */
813 "NV is too small",
814 /* 45 - TSS2_BASE_RC_NV_NOT_WRITEABLE */
815 "NV is not writable",
816 /* 46 - TSS2_BASE_RC_POLICY_UNKNOWN */
817 "The policy is unknown",
818 /* 47 - TSS2_BASE_RC_NV_WRONG_TYPE */
819 "The NV type is wrong",
820 /* 48 - TSS2_BASE_RC_NAME_ALREADY_EXISTS */
821 "The name already exists",
822 /* 49 - TSS2_BASE_RC_NO_TPM */
823 "No TPM available",
824 /* 50 - TSS2_BASE_RC_BAD_KEY */
825 "The key is bad",
826 /* 51 - TSS2_BASE_RC_NO_HANDLE */
827 "No handle provided"
770828 };
771829
772830 return (rc - 1u < ARRAY_LEN(errors)) ? errors[rc - 1u] : NULL;
783841 ADD_NULL_HANDLER, /* layer 3 is unused */
784842 ADD_NULL_HANDLER, /* layer 4 is unused */
785843 ADD_NULL_HANDLER, /* layer 5 is unused */
786 ADD_HANDLER("fapi", NULL), /* layer 6 is the fapi rc */
787 ADD_HANDLER("esapi", sys_err_handler), /* layer 7 is the esapi rc */
788 ADD_HANDLER("sys", sys_err_handler), /* layer 8 is the sys rc */
789 ADD_HANDLER("mu", sys_err_handler), /* layer 9 is the mu rc */
844 ADD_HANDLER("fapi", tss_err_handler), /* layer 6 is the fapi rc */
845 ADD_HANDLER("esapi", tss_err_handler), /* layer 7 is the esapi rc */
846 ADD_HANDLER("sys", tss_err_handler), /* layer 8 is the sys rc */
847 ADD_HANDLER("mu", tss_err_handler), /* layer 9 is the mu rc */
790848 /* Defaults to the system handler */
791 ADD_HANDLER("tcti", sys_err_handler), /* layer 10 is the tcti rc */
849 ADD_HANDLER("tcti", tss_err_handler), /* layer 10 is the tcti rc */
792850 /* Defaults to the system handler */
793851 ADD_HANDLER("rmt", tpm2_ehandler), /* layer 11 is the resource manager TPM RC */
794852 /* The RM usually duplicates TPM responses */
2222 TSS2_RC rval = TSS2_RC_SUCCESS;
2323 size_t offset = 0, offset_tmp;
2424 unsigned i = 0;
25 UINT32 rspParamsSize;
2526
2627 if (!ctx || !rspAuthsArray)
2728 return TSS2_SYS_RC_BAD_REFERENCE;
3637
3738 offset += sizeof(TPM20_Header_Out);
3839 offset += ctx->numResponseHandles * sizeof(TPM2_HANDLE);
39 offset += BE_TO_HOST_32(*ctx->rspParamsSize);
40 memcpy(&rspParamsSize, ctx->rspParamsSize, sizeof(rspParamsSize));
41 offset += BE_TO_HOST_32(rspParamsSize);
4042 offset += sizeof(UINT32);
4143 offset_tmp = offset;
4244
1919 const TSS2L_SYS_AUTH_COMMAND *cmdAuthsArray)
2020 {
2121 _TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
22 uint8_t i;
22 uint16_t i;
2323 UINT32 authSize = 0;
2424 UINT32 newCmdSize = 0;
2525 size_t authOffset;
6767 ctx->cpBuffer, ctx->cpBufferUsedSize);
6868
6969 /* Reset the auth size field */
70 *(UINT32 *)ctx->cpBuffer = 0;
70 memset(ctx->cpBuffer, 0, sizeof(UINT32));
7171
7272 /* Now copy in the authorization area. */
7373 authOffset = ctx->cpBuffer - ctx->cmdBuffer;
109109 TSS2_RC ValidateNV_Public(const TPM2B_NV_PUBLIC *nv_public_info);
110110 TSS2_RC ValidateTPML_PCR_SELECTION(const TPML_PCR_SELECTION *pcr_selection);
111111
112 TSS2_SYS_CONTEXT *InitSysContext(
113 UINT16 maxCommandSize,
114 TSS2_TCTI_CONTEXT *tctiContext,
115 TSS2_ABI_VERSION *abiVersion);
116
117 void TeardownSysContext(TSS2_SYS_CONTEXT **ctx);
118
119112 #ifdef __cplusplus
120113 }
121114 #endif
5555 #define LOGMODULE tcti
5656 #include "util/log.h"
5757
58 #define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
59
60 static char *default_conf[] = {
5861 #ifdef __VXWORKS__
59 #define TCTI_DEVICE_DEFAULT "/tpm0"
62 "/tpm0"
6063 #else
61 #define TCTI_DEVICE_DEFAULT "/dev/tpm0"
62 #endif
64 "/dev/tpmrm0",
65 "/dev/tpm0",
66 #endif /* __VX_WORKS__ */
67 };
6368
6469 /*
6570 * This function wraps the "up-cast" of the opaque TCTI context type to the
179184 */
180185 if (timeout != TSS2_TCTI_TIMEOUT_BLOCK) {
181186 LOG_WARNING ("The underlying IPC mechanism does not support "
182 "asynchronous I/O. The 'timeout' parameter must be "
187 "asynchronous I/O. The 'timeout' parameter is set to "
183188 "TSS2_TCTI_TIMEOUT_BLOCK");
184 return TSS2_TCTI_RC_BAD_VALUE;
189 timeout = TSS2_TCTI_TIMEOUT_BLOCK;
185190 }
186191 #endif
187192 if (response_buffer == NULL) {
367372 return TSS2_TCTI_RC_BAD_CONTEXT;
368373 }
369374
370 if (handles == NULL || num_handles == NULL) {
375 if (num_handles == NULL) {
371376 return TSS2_TCTI_RC_BAD_REFERENCE;
372377 }
373378
379 if (handles != NULL && *num_handles < 1) {
380 return TSS2_TCTI_RC_INSUFFICIENT_BUFFER;
381 }
382
374383 *num_handles = 1;
375 handles->fd = tcti_dev->fd;
384 if (handles != NULL) {
385 handles->fd = tcti_dev->fd;
386 }
387
376388 return TSS2_RC_SUCCESS;
377389 #else
378390 (void)(tctiContext);
396408 return TSS2_TCTI_RC_NOT_IMPLEMENTED;
397409 }
398410
411 static int open_tpm (
412 const char* pathname) {
413 #ifdef __VXWORKS__
414 return open (pathname, O_RDWR, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
415 #else
416 return open (pathname, O_RDWR | O_NONBLOCK);
417 #endif
418 }
419
399420 TSS2_RC
400421 Tss2_Tcti_Device_Init (
401422 TSS2_TCTI_CONTEXT *tctiContext,
404425 {
405426 TSS2_TCTI_DEVICE_CONTEXT *tcti_dev;
406427 TSS2_TCTI_COMMON_CONTEXT *tcti_common;
407 const char *dev_path = conf != NULL ? conf : TCTI_DEVICE_DEFAULT;
408428
409429 if (tctiContext == NULL && size == NULL) {
410430 return TSS2_TCTI_RC_BAD_VALUE;
429449 memset (&tcti_common->header, 0, sizeof (tcti_common->header));
430450 tcti_common->locality = 3;
431451
432 #ifdef __VXWORKS__
433 tcti_dev->fd = open (dev_path, O_RDWR, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
434 #else
435 tcti_dev->fd = open (dev_path, O_RDWR | O_NONBLOCK);
436 #endif
437 if (tcti_dev->fd < 0) {
438 LOG_ERROR ("Failed to open device file %s: %s",
439 dev_path, strerror (errno));
440 return TSS2_TCTI_RC_IO_ERROR;
441 }
452 if (conf == NULL) {
453 LOG_TRACE ("No TCTI device file specified");
454
455 for (size_t i = 0; i < ARRAY_LEN(default_conf); i++) {
456 LOG_DEBUG ("Trying to open default TCTI device file %s",
457 default_conf[i]);
458 tcti_dev->fd = open_tpm (default_conf[i]);
459 if (tcti_dev->fd >= 0) {
460 LOG_TRACE ("Successfully opened default TCTI device file %s",
461 default_conf[i]);
462 break;
463 } else {
464 LOG_WARNING ("Failed to open default TCTI device file %s: %s",
465 default_conf[i], strerror (errno));
466 }
467 }
468 if (tcti_dev->fd < 0) {
469 LOG_ERROR ("Could not open any default TCTI device file");
470 return TSS2_TCTI_RC_IO_ERROR;
471 }
472 } else {
473 LOG_DEBUG ("Trying to open specified TCTI device file %s", conf);
474 tcti_dev->fd = open_tpm (conf);
475 if (tcti_dev->fd < 0) {
476 LOG_ERROR ("Failed to open specified TCTI device file %s: %s",
477 conf, strerror (errno));
478 return TSS2_TCTI_RC_IO_ERROR;
479 } else {
480 LOG_TRACE ("Successfully opened specified TCTI device file %s", conf);
481 }
482 }
483
442484
443485 return TSS2_RC_SUCCESS;
444486 }
303303 unsigned char *response_buffer,
304304 int32_t timeout)
305305 {
306 #ifdef TEST_FAPI_ASYNC
307 /* Used for simulating a timeout. */
308 static int wait = 0;
309 #endif
306310 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = tcti_mssim_context_cast (tctiContext);
307311 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_mssim_down_cast (tcti_mssim);
308312 TSS2_RC rc;
318322 }
319323
320324 if (timeout != TSS2_TCTI_TIMEOUT_BLOCK) {
321 LOG_WARNING ("Asynchronous I/O not implemented. The 'timeout' "
322 "parameter must be TSS2_TCTI_TIMEOUT_BLOCK.");
323 return TSS2_TCTI_RC_BAD_VALUE;
325 LOG_TRACE("Asynchronous I/O not actually implemented.");
326 #ifdef TEST_FAPI_ASYNC
327 if (wait < 1) {
328 LOG_TRACE("Simulating Async by requesting another invocation.");
329 wait += 1;
330 return TSS2_TCTI_RC_TRY_AGAIN;
331 } else {
332 LOG_TRACE("Sending the actual result.");
333 wait = 0;
334 }
335 #endif /* TEST_FAPI_ASYNC */
324336 }
325337
326338 if (tcti_common->header.size == 0) {
345357 LOG_DEBUG ("response size: %" PRIu32, tcti_common->header.size);
346358 }
347359
348 *response_size = tcti_common->header.size;
349360 if (response_buffer == NULL) {
361 *response_size = tcti_common->header.size;
350362 return TSS2_RC_SUCCESS;
351363 }
352364
354366 *response_size = tcti_common->header.size;
355367 return TSS2_TCTI_RC_INSUFFICIENT_BUFFER;
356368 }
369 *response_size = tcti_common->header.size;
357370
358371 /* Receive the TPM response. */
359372 LOG_DEBUG ("Reading response of size %" PRIu32, tcti_common->header.size);
4040 {
4141 .file = "libtss2-tcti-device.so.0",
4242 .conf = "/dev/tpmrm0",
43 .description = "Access libtss2-tcti-device.s0 with /dev/tpmrm0",
43 .description = "Access libtss2-tcti-device.so.0 with /dev/tpmrm0",
4444 },
4545 {
4646 .file = "libtss2-tcti-device.so.0",
4747 .conf = "/dev/tpm0",
48 .description = "Access libtss2-tcti-device.s0 with /dev/tpmrm0",
48 .description = "Access libtss2-tcti-device.so.0 with /dev/tpm0",
4949 },
5050 {
5151 .file = "libtss2-tcti-mssim.so.0",
181181 else if (handle == NULL)
182182 return TSS2_TCTI_RC_IO_ERROR;
183183 #else
184 for (size_t i = 0; i < ARRAY_SIZE(tctis); i++) {
184 size_t i;
185 for (i = 0; i < ARRAY_SIZE(tctis); i++) {
185186 name = tctis[i].file;
186187 LOG_DEBUG("name: %s", name);
187188 if (name == NULL) {
233234 #else /* ESYS_TCTI_DEFAULT_MODULE */
234235
235236 TSS2_RC r;
236
237 for (size_t i = 0; i < ARRAY_SIZE(tctis); i++) {
237 size_t i;
238
239 for (i = 0; i < ARRAY_SIZE(tctis); i++) {
238240 LOG_DEBUG("Attempting to connect using standard TCTI: %s",
239241 tctis[i].description);
240242 r = tcti_from_file(tctis[i].file, tctis[i].conf, tcticontext,
1414 #include <linux/limits.h>
1515 #elif defined(_MSC_VER)
1616 #include <windows.h>
17 #include <limits.h>
1718 #ifndef PATH_MAX
1819 #define PATH_MAX MAX_PATH
20
21 static char *strndup(const char* s, size_t n)
22 {
23 char *dst = NULL;
24
25 if (n + 1 >= USHRT_MAX)
26 return NULL;
27
28 dst = calloc(1, n + 1);
29
30 if (dst == NULL)
31 return NULL;
32
33 memcpy(dst, s, n);
34 return dst;
35 }
1936 #endif
2037 #else
2138 #include <limits.h>
116133 char *split;
117134 size_t combined_length;
118135
119 LOG_DEBUG ("name_conf: \"%s\"", name_conf);
120136 if (name_conf == NULL) {
121137 LOG_ERROR ("'name_conf' param may NOT be NULL");
122138 return TSS2_TCTI_RC_BAD_REFERENCE;
126142 LOG_ERROR ("combined conf length must be between 0 and PATH_MAX");
127143 return TSS2_TCTI_RC_BAD_VALUE;
128144 }
145
146 LOG_DEBUG ("name_conf: \"%s\"", name_conf);
129147 if (combined_length == 0)
130148 return TSS2_RC_SUCCESS;
131149 split = strchr (name_conf, ':');
267285 *tctiContext = NULL;
268286 }
269287
270 #if !defined(HAVE_STRNDUP)
271 char*
272 strndup (const char* s,
273 size_t n)
274 {
275 char* dst = NULL;
276
277 if (n + 1 < n) {
278 return NULL;
279 }
280 dst = calloc(1, n + 1);
281 if (dst == NULL) {
282 return NULL;
283 }
284 memcpy(dst, s, n);
285
286 return dst;
287 }
288 #endif /* HAVE_STRNDUP */
289
290288 TSS2_RC
291289 copy_info (const TSS2_TCTI_INFO *info_src,
292290 TSS2_TCTI_INFO *info_dst)
366364 info_tmp->init = NULL;
367365 out:
368366 tctildr_finalize_data (&data);
369 *info = info_tmp ? info_tmp : NULL;
367 *info = info_tmp;
370368 return rc;
371369 }
372370
419417 }
420418 ldr_ctx = calloc (1, sizeof (TSS2_TCTILDR_CONTEXT));
421419 if (ldr_ctx == NULL) {
420 rc = TSS2_TCTI_RC_MEMORY;
422421 goto err;
423422 }
424423 TSS2_TCTI_MAGIC (ldr_ctx) = TCTILDR_MAGIC;
77 #endif
88
99 #include <errno.h>
10 #include <fcntl.h>
1011 #include <inttypes.h>
1112 #include <limits.h>
1213 #include <string.h>
8181 {
8282 if (unlikely(*status == LOGLEVEL_UNDEFINED))
8383 *status = getLogLevel(module, logdefault);
84
8584 if (loglevel > *status)
8685 return;
87
88 size_t width = 8;
89 size_t buffer_size = (size * 2) + (size / width) * 2 + 1;
90 char buffer[buffer_size];
91 buffer[0] = '\0';
92 for (size_t i = 0, off = 0; i < size && off < buffer_size; i++, off+=2) {
93 if (width < buffer_size && i % width == 0) {
94 *(&buffer[0] + off) = '\n';
95 off += 1;
96 *(&buffer[0] + off) = '\t';
97 off += 1;
98 }
99 sprintf(&buffer[0] + off, "%02x", blob[i]);
100 }
10186
10287 va_list vaargs;
10388 va_start(vaargs, fmt);
11196 va_end(vaargs);
11297
11398 doLog(loglevel, module, logdefault, status, file, func, line,
114 "%s (size=%zi): %s", msg, size, buffer);
99 "%s (size=%zi):", msg, size);
100
101 unsigned int i, y, x, off, off2;
102 unsigned int width = 16;
103 #define LINE_LEN 64
104 char buffer[LINE_LEN];
105
106 for (i = 1, off = 0, off2 = 0; i <= size; i++) {
107 if (i == 1) {
108 sprintf(&buffer[off], "%04x: ", i - 1);
109 off += 6;
110 }
111
112 /* data output */
113 sprintf(&buffer[off], "%02x", blob[i-1]);
114 off += 2;
115
116 /* ASCII output */
117 if ((i % width == 0 && i > 1) || i == size) {
118 sprintf(&buffer[off], " ");
119 off += 2;
120 /* Align to the right */
121 for (x = off; x < width * 2 + 8; x++) {
122 sprintf(&buffer[off], " ");
123 off++;
124 }
125
126 /* Account for a line that is not 'full' */
127 unsigned int less = width - (i % width);
128 if (less == width)
129 less = 0;
130
131 for (y = 0; y < width - less; y++) {
132 if (isgraph(blob[off2 + y])) {
133 sprintf(&buffer[y + off], "%c", blob[off2 + y]);
134 } else {
135 sprintf(&buffer[y + off], "%c", '.');
136 }
137 }
138 /* print the line and restart */
139 fprintf (stderr, "%s\n", buffer);
140 off2 = i;
141 off = 0;
142 memset(buffer, '\0', LINE_LEN);
143 sprintf(&buffer[off], "%04x: ", i);
144 off += 6;
145 }
146 }
115147 }
116148
117149 void
143175 static log_level
144176 log_stringlevel(const char *n)
145177 {
146 for(log_level i = 0; i < sizeof(log_strings)/sizeof(log_strings[0]); i++) {
178 log_level i;
179 for(i = 0; i < sizeof(log_strings)/sizeof(log_strings[0]); i++) {
147180 if (case_insensitive_strncmp(log_strings[i], n, strlen(log_strings[i])) == 0) {
148181 return i;
149182 }
88 #define TSS2_ENDIAN_H
99
1010 #if defined(__linux__) || defined(__unix__)
11 #if defined(__FreeBSD__)
12 #include <sys/endian.h>
13 #else
1114 #include <endian.h>
15 #endif
1216
1317 #define HOST_TO_BE_16(value) htobe16(value)
1418 #define HOST_TO_BE_32(value) htobe32(value)
0 {
1 "type": "TPM2_ALG_ECC",
2 "nameAlg":"TPM2_ALG_SHA256",
3 "srk_template": "system,restricted,decrypt,0x81000001",
4 "srk_persistent": 0,
5 "ek_template": "system,restricted,decrypt",
6 "ecc_signing_scheme": {
7 "scheme":"TPM2_ALG_ECDSA",
8 "details":{
9 "hashAlg":"TPM2_ALG_SHA256"
10 },
11 },
12 "sym_mode":"TPM2_ALG_CFB",
13 "sym_parameters": {
14 "algorithm":"TPM2_ALG_AES",
15 "keyBits":"128",
16 "mode":"TPM2_ALG_CFB"
17 },
18 "sym_block_size": 16,
19 "pcr_selection": [
20 { "hash": "TPM2_ALG_SHA1",
21 "pcrSelect": [ ],
22 },
23 { "hash": "TPM2_ALG_SHA256",
24 "pcrSelect": [ 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ]
25 }
26 ],
27 "curveID": "TPM2_ECC_NIST_P256",
28 "ek_policy": {
29 "description": "Endorsement hierarchy used for policy secret.",
30 "policy":[
31 {
32 "type":"POLICYSECRET",
33 "objectName": "4000000b",
34 }
35 ]
36 }
37 }
0 {
1 "type": "TPM2_ALG_RSA",
2 "nameAlg":"TPM2_ALG_SHA256",
3 "srk_template": "system,restricted,decrypt,0x81000001",
4 "srk_persistent": 1,
5 "ek_template": "system,restricted,decrypt",
6 "rsa_signing_scheme": {
7 "scheme":"TPM2_ALG_RSAPSS",
8 "details":{
9 "hashAlg":"TPM2_ALG_SHA256"
10 }
11 },
12 "rsa_decrypt_scheme": {
13 "scheme":"TPM2_ALG_OAEP",
14 "details":{
15 "hashAlg":"TPM2_ALG_SHA256"
16 }
17 },
18 "sym_mode":"TPM2_ALG_CFB",
19 "sym_parameters": {
20 "algorithm":"TPM2_ALG_AES",
21 "keyBits":"128",
22 "mode":"TPM2_ALG_CFB"
23 },
24 "sym_block_size": 16,
25 "pcr_selection": [
26 { "hash": "TPM2_ALG_SHA1",
27 "pcrSelect": [ ]
28 },
29 { "hash": "TPM2_ALG_SHA256",
30 "pcrSelect": [ 8, 9 , 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ]
31 }
32 ],
33 "exponent": 0,
34 "keyBits": 2048,
35 "session_hash_alg": "TPM2_ALG_SHA256",
36 "session_symmetric":{
37 "algorithm":"TPM2_ALG_AES",
38 "keyBits":"128",
39 "mode":"TPM2_ALG_CFB"
40 },
41 "ek_policy": {
42 "description": "Endorsement hierarchy used for policy secret.",
43 "policy":[
44 {
45 "type":"POLICYSECRET",
46 "objectName": "4000000b",
47 }
48 ]
49 }
50
51 }
0 {
1 "type": "TPM2_ALG_RSA",
2 "nameAlg":"TPM2_ALG_SHA256",
3 "srk_template": "system,restricted,decrypt",
4 "srk_persistent": 0,
5 "ek_template": "system,restricted,decrypt",
6 "ecc_signing_scheme": {
7 "scheme":"TPM2_ALG_ECDSA",
8 "details":{
9 "hashAlg":"TPM2_ALG_SHA1"
10 },
11 },
12 "rsa_signing_scheme": {
13 "scheme":"TPM2_ALG_RSAPSS",
14 "details":{
15 "hashAlg":"TPM2_ALG_SHA256"
16 }
17 },
18 "rsa_decrypt_scheme": {
19 "scheme":"TPM2_ALG_OAEP",
20 "details":{
21 "hashAlg":"TPM2_ALG_SHA1"
22 }
23 },
24 "sym_mode":"TPM2_ALG_CFB",
25 "sym_parameters": {
26 "algorithm":"TPM2_ALG_AES",
27 "keyBits":"128",
28 "mode":"TPM2_ALG_CFB"
29 },
30 "sym_block_size": 16,
31 "pcr_selection": [
32 { "hash": "TPM2_ALG_SHA1",
33 "pcrSelect": [ 9, 15, 13]
34 },
35 { "hash": "TPM2_ALG_SHA256",
36 "pcrSelect": [ 8, 16, 14 ]
37 }
38 ],
39 "exponent": 0,
40 "keyBits": 2048
41 }
0 {
1 "type": "TPM2_ALG_RSA",
2 "nameAlg":"TPM2_ALG_SHA256",
3 "srk_template": "system,restricted,decrypt",
4 "srk_persistent": 0,
5 "ek_template": "system,restricted,decrypt,0x81000000",
6 "ecc_signing_scheme": {
7 "scheme":"TPM2_ALG_ECDSA",
8 "details":{
9 "hashAlg":"TPM2_ALG_SHA1"
10 },
11 },
12 "rsa_signing_scheme": {
13 "scheme":"TPM2_ALG_RSAPSS",
14 "details":{
15 "hashAlg":"TPM2_ALG_SHA1"
16 }
17 },
18 "rsa_decrypt_scheme": {
19 "scheme":"TPM2_ALG_OAEP",
20 "details":{
21 "hashAlg":"TPM2_ALG_SHA1"
22 }
23 },
24 "sym_mode":"TPM2_ALG_CFB",
25 "sym_parameters": {
26 "algorithm":"TPM2_ALG_AES",
27 "keyBits":"128",
28 "mode":"TPM2_ALG_CFB"
29 },
30 "sym_block_size": 16,
31 "pcr_selection": [
32 { "hash": "TPM2_ALG_SHA1",
33 "pcrSelect": [ 9, 15 ]
34 },
35 { "hash": "TPM2_ALG_SHA256",
36 "pcrSelect": [ 8, 16 ]
37 }
38 ],
39 "exponent": 0,
40 "keyBits": 2048
41 }
0 {
1 "type": "TPM2_ALG_RSA",
2 "nameAlg":"TPM2_ALG_SHA256",
3 "srk_template": "system,restricted,decrypt,0x81000001",
4 "srk_persistent": 1,
5 "ek_template": "system,restricted,decrypt",
6 "rsa_signing_scheme": {
7 "scheme":"TPM2_ALG_RSAPSS",
8 "details":{
9 "hashAlg":"TPM2_ALG_SHA1"
10 }
11 },
12 "rsa_decrypt_scheme": {
13 "scheme":"TPM2_ALG_OAEP",
14 "details":{
15 "hashAlg":"TPM2_ALG_SHA1"
16 }
17 },
18 "sym_mode":"TPM2_ALG_CFB",
19 "sym_parameters": {
20 "algorithm":"TPM2_ALG_AES",
21 "keyBits":"128",
22 "mode":"TPM2_ALG_CFB"
23 },
24 "sym_block_size": 16,
25 "pcr_selection": [
26 { "hash": "TPM2_ALG_SHA1",
27 "pcrSelect": [ 9, 15, 13 ]
28 },
29 { "hash": "TPM2_ALG_SHA256",
30 "pcrSelect": [ 8, 16, 14 ]
31 }
32 ],
33 "exponent": 0,
34 "keyBits": 2048,
35 "session_hash_alg": "TPM2_ALG_SHA256",
36 "session_symmetric":{
37 "algorithm":"TPM2_ALG_AES",
38 "keyBits":"128",
39 "mode":"TPM2_ALG_CFB"
40 },
41 "ek_policy": {
42 "description": "Endorsement hierarchy used for policy secret.",
43 "policy":[
44 {
45 "type":"POLICYSECRET",
46 "objectName": "4000000b",
47 }
48 ]
49 },
50 "sh_policy": {
51 "description":"Description pol_16_0",
52 "policy":[
53 {
54 "type":"POLICYPCR",
55 "pcrs":[
56 {
57 "pcr":16,
58 "hashAlg":"TPM2_ALG_SHA",
59 "digest":"0000000000000000000000000000000000000000"
60 }
61 ]
62 }
63 ]
64 }
65 }
0 {
1 "shortname":"pol_password",
2 "description":"Description pol_password",
3 "policyDigests":[
4 ],
5 "policyAuthorizations":[
6 ],
7 "policy":[
8 {
9 "type": "POLICYPASSWORD",
10 "policyDigests":[],
11 "element":{
12 }
13 }
14 ]
15 }
0 {
1 "description":"The description",
2 "policy":[
3 {
4 "type": "POLICYACTION",
5 "action": "myaction"
6 }
7 ]
8 }
0 {
1 "description":"Description pol_auth_value",
2 "policy":[
3 {
4 "type": "POLICYAUTHVALUE",
5 }
6 ]
7 }
0 {
1 "description":"Description pol_authorize",
2 "policy":[
3 {
4 "type": "POLICYAUTHORIZE",
5 "policyRef": [ 1, 2, 3, 4, 5 ],
6 "keyPath": "/HS/SRK/myPolicySignKey",
7 }
8 ]
9 }
0 {
1 "description":"Description pol_authorize_nv",
2 "policy":[
3 {
4 "type": "POLICYAUTHORIZENV",
5 "nvPath": "/nv/Owner/myNV",
6 }
7 ]
8 }
0 {
1 "description":"Description pol_authorize",
2 "policy":[
3 {
4 "type": "POLICYAUTHORIZE",
5 "keyPath": "/HS/SRK/myPolicySignKeyOuter",
6 }
7 ]
8 }
0 {
1 "description":"Description pol_auth_value",
2 "policy":[
3 {
4 "type": "POLICYCOMMANDCODE",
5 "code": 349
6 }
7 ]
8 }
0 {
1 "description":"Description pol_countertimer",
2 "policy":[
3 {
4 "type": "POLICYCOUNTERTIMER",
5 "operandB": "ff",
6 "operation": "UNSIGNED_LT"
7 }
8 ]
9 }
0 {
1 "description":"Policy CpHash",
2 "policy":[
3 {
4 "type": "POLICYCPHASH",
5 "cpHash": "d1b4d44f20fa696f638e4f8a9cfceae97f9dee388143929eeea8982259b8f402"
6 }
7 ]
8 }
0 {
1 "description":"Description pol_duplicate",
2 "policy":[
3 {
4 "type": "POLICYDUPLICATIONSELECT",
5 "newParentPath": "ext/myNewParent",
6 }
7 ]
8 }
0 {
1 "description":"Description pol_auth_value",
2 "policy":[
3 {
4 "type": "POLICYLOCALITY",
5 "locality": 1
6 }
7 ]
8 }
0 {
1 "description":"Policy NameHash",
2 "policy":[
3 {
4 "type": "POLICYNAMEHASH",
5 "namePaths": [ "/HS/SRK/mySignKey" ]
6 }
7 ]
8 }
0 {
1 "description":"Description pol_nv",
2 "policy":[
3 {
4 "type": "POLICYNV",
5 "nvPath": "/nv/Owner/myNV",
6 "operandB": "01020304",
7 "operation": "EQ"
8 }
9 ]
10 }
0 {
1 "description":"Description pol_auth_value",
2 "policy":[
3 {
4 "type": "POLICYAUTHVALUE",
5 },
6 {
7 "type": "POLICYCOMMANDCODE",
8 "code": 315
9 }
10 ]
11 }
0 {
1 "description":"Description pol_password",
2 "policy":[
3 {
4 "type": "POLICYNVWRITTEN",
5 "writtenSet": "NO"
6 }
7 ]
8 }
0 {
1 "description":"Description pol_password",
2 "policy":[
3 {
4 "type": "POLICYPASSWORD",
5 }
6 ]
7 }
0 {
1 "description":"Description pol_16_0",
2
3 "policy":[
4 {
5 "type":"POLICYPCR",
6 "pcrs":[
7 {
8 "pcr":16,
9 "hashAlg":"TPM2_ALG_SHA",
10 "digest":"0000000000000000000000000000000000000000"
11 }
12 ]
13 }
14 ]
15 }
0 {
1 "description":"Description pol_16_0",
2 "policy":[
3 {
4 "type":"POLICYPCR",
5 "pcrs":[
6 {
7 "pcr":16,
8 "hashAlg":"TPM2_ALG_SHA",
9 "digest":"0000000000000000000000000000000000000001"
10 }
11 ]
12 }
13 ]
14 }
0 {
1 "description":"hareness description",
2 "policy":[
3 {
4 "type":"POLICYOR",
5 "branches":[
6 {
7 "name":"branch0",
8 "description":"description branch 0",
9 "policy":[
10 {
11 "type":"POLICYPCR",
12 "pcrs":[
13 {
14 "pcr":16,
15 "hashAlg":"TPM2_ALG_SHA",
16 "digest":"0000000000000000000000000000000000000000"
17 }
18 ]
19 }
20 ],
21 },
22 {
23 "name":"branch1",
24 "description":"description branch 1",
25 "policy":[
26 {
27 "type":"POLICYPCR",
28 "pcrs":[
29 {
30 "pcr":16,
31 "hashAlg":"TPM2_ALG_SHA",
32 "digest":"AA000000000000000000000000000000000000AA"
33 }
34 ]
35 }
36 ],
37 }
38 ]
39 }
40 ]
41 }
0 {
1 "description":"Description pol_16_0",
2
3 "policy":[
4 {
5 "type":"POLICYPCR",
6 "currentPCRs":[ 15 ]
7 }
8 ]
9 }
0 {
1 "description":"Description pol_auth_value",
2 "policy":[
3 {
4 "type": "POLICYPHYSICALPRESENCE",
5
6 }
7 ]
8 }
0 {
1 "description":"Description pol_authorize",
2 "policy":[
3 {
4 "type": "POLICYSECRET",
5 "objectPath": "/nv/Owner/myNV",
6 }
7 ]
8 }
0 {
1 "description":"Description pol_signed",
2 "policy":[
3 {
4 "type": "POLICYSIGNED",
5 "publicKeyHint": "Test key hint",
6 "keyPEM": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoGL6IrCSAznmIIzBessI\nmW7tPOUy78uWTIaub32KnYHn78KXprrZ3ykp6WDrOQeMjv4AA+14mJbg77apVYXy\nEnkFdOMa1hszSJnp6cJvx7ILngLvFUxzbVki\/ehvgS3nRk67Njal+nMTe8hpe3UK\nQeV\/Ij+F0r6Yz91W+4LPmncAiUesRZLetI2BZsKwHYRMznmpIYpoua1NtS8QpEXR\nMmsUue19eS\/XRAPmmCfnb5BX2Tn06iCpk6wO+RfMo9etcX5cLSAuIYEQYCvV2\/0X\nTfEw607vttBN0Y54LrVOKno1vRXd5sxyRlfB0WL42F4VG5TfcJo5u1Xq7k9m9K57\n8wIDAQAB\n-----END PUBLIC KEY-----\n",
7 "keyPEMhashAlg": "SHA1"
8 }
9 ]
10 }
0 {
1 "description":"Description pol_signed",
2 "policy":[
3 {
4 "type": "POLICYSIGNED",
5 "keyPEM": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoJTa3zftdAzHC96IjpqQ/dnLm+p7\npEiLMi03Jd0oP0aYnnXFjolzIB/dBZ/t+BLh0PwLM5aAM/jugeLkHgpIyQ==\n-----END PUBLIC KEY-----\n",
6 "keyPEMhashAlg": "SHA1"
7 }
8 ]
9 }
0 #ifdef HAVE_CONFIG_H
1 #include <config.h>
2 #endif
3
4 #include <stdbool.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include <openssl/evp.h>
9 #include <openssl/rsa.h>
10 #include <openssl/pem.h>
11
12 #include "tss2_sys.h"
13 #include "tss2_mu.h"
14
15 #define LOGMODULE test
16 #include "util/log.h"
17 #include "test-options.h"
18 #include "context-util.h"
19
20 int
21 main (int argc, char *argv[])
22 {
23 TSS2_RC rc;
24 TSS2_SYS_CONTEXT *sapi_context;
25 TSS2L_SYS_AUTH_COMMAND auth_cmd = {
26 .auths = {{ .sessionHandle = TPM2_RS_PW }},
27 .count = 1
28 };
29 TPM2B_SENSITIVE_CREATE in_sensitive = { 0 };
30 TPM2B_PUBLIC in_public = {
31 .publicArea = {
32 .type = TPM2_ALG_RSA,
33 .nameAlg = TPM2_ALG_SHA256,
34 .objectAttributes = (
35 TPMA_OBJECT_FIXEDTPM |
36 TPMA_OBJECT_FIXEDPARENT |
37 TPMA_OBJECT_SENSITIVEDATAORIGIN |
38 TPMA_OBJECT_ADMINWITHPOLICY |
39 TPMA_OBJECT_RESTRICTED |
40 TPMA_OBJECT_DECRYPT
41 ),
42 .authPolicy = {
43 .size = 32,
44 .buffer = 0x83, 0x71, 0x97, 0x67, 0x44, 0x84,
45 0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D,
46 0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52,
47 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
48 0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14,
49 0x69, 0xAA,
50 },
51 .parameters.rsaDetail = {
52 .symmetric = {
53 .algorithm = TPM2_ALG_AES,
54 .keyBits.aes = 128,
55 .mode.aes = TPM2_ALG_CFB,
56 },
57 .scheme = {
58 .scheme = TPM2_ALG_NULL,
59 },
60 .keyBits = 2048,
61 .exponent = 0,
62 },
63 .unique.rsa = {
64 .size = 256,
65 .buffer = {0},
66 }
67 }
68 };
69 TPML_PCR_SELECTION creation_pcr = { 0 };
70 TPM2_HANDLE handle;
71 TPM2B_PUBLIC out_public = { 0 };
72 TSS2L_SYS_AUTH_RESPONSE auth_rsp = {
73 .count = 0
74 };
75
76 test_opts_t opts = {
77 .tcti_type = TCTI_DEFAULT,
78 .device_file = DEVICE_PATH_DEFAULT,
79 .socket_address = HOSTNAME_DEFAULT,
80 .socket_port = PORT_DEFAULT,
81 };
82
83 get_test_opts_from_env (&opts);
84 if (sanity_check_test_opts (&opts) != 0)
85 exit (1);
86
87 sapi_context = sapi_init_from_opts (&opts);
88 if (sapi_context == NULL)
89 exit (1);
90
91 /* Generate the EK key */
92
93 rc = Tss2_Sys_CreatePrimary(sapi_context, TPM2_RH_ENDORSEMENT, &auth_cmd,
94 &in_sensitive, &in_public, NULL, &creation_pcr,
95 &handle, &out_public, NULL, NULL, NULL, NULL, &auth_rsp);
96 if (rc != TSS2_RC_SUCCESS) {
97 LOG_ERROR("TPM CreatePrimary FAILED: 0x%"PRIx32, rc);
98 exit(1);
99 }
100
101 rc = Tss2_Sys_FlushContext(sapi_context, handle);
102 if (rc != TSS2_RC_SUCCESS) {
103 LOG_ERROR("TPM FlushContext FAILED: 0x%"PRIx32, rc);
104 exit(1);
105 }
106
107 sapi_teardown_full (sapi_context);
108
109 /* Convert the key from out_public to PEM */
110
111 EVP_PKEY *evp = EVP_PKEY_new();
112 BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE);
113 RSA *rsa = RSA_new();
114 BIGNUM *e = BN_new();
115 BIGNUM *d = BN_new();
116 BIGNUM *p = BN_new();
117 BIGNUM *q = BN_new();
118 BIGNUM *dmp1 = BN_new();
119 BIGNUM *dmq1 = BN_new();
120 BIGNUM *iqmp = BN_new();
121 BIGNUM *n = BN_bin2bn(out_public.publicArea.unique.rsa.buffer,
122 out_public.publicArea.unique.rsa.size, NULL);
123 BN_set_word(d, 0);
124 BN_set_word(p, 0);
125 BN_set_word(q, 0);
126 BN_set_word(dmp1, 0);
127 BN_set_word(dmq1, 0);
128 BN_set_word(iqmp, 0);
129 uint32_t exp;
130 if (out_public.publicArea.parameters.rsaDetail.exponent == 0)
131 exp = 65537;
132 else
133 exp = out_public.publicArea.parameters.rsaDetail.exponent;
134 BN_set_word(e, exp);
135
136 #if OPENSSL_VERSION_NUMBER < 0x10100000
137 rsa->e = e;
138 rsa->n = n;
139 rsa->d = d;
140 rsa->p = p;
141 rsa->q = q;
142 rsa->dmp1 = dmp1;
143 rsa->dmq1 = dmq1;
144 rsa->iqmp = iqmp;
145 #else /* OPENSSL_VERSION_NUMBER < 0x10100000 */
146 RSA_set0_key(rsa, n, e, d);
147 RSA_set0_factors(rsa, p, q);
148 RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
149 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
150
151 EVP_PKEY_assign_RSA(evp, rsa);
152
153 if (!PEM_write_bio_PUBKEY(bio, evp)) {
154 LOG_ERROR("PEM_write failed");
155 exit(1);
156 }
157
158 EVP_PKEY_free(evp);
159 BIO_free(bio);
160
161 return 0;
162 }
0 #ifdef HAVE_CONFIG_H
1 #include <config.h>
2 #endif
3
4 #include <stdbool.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include <openssl/evp.h>
9 #include <openssl/rsa.h>
10 #include <openssl/pem.h>
11 #include <openssl/err.h>
12 #include <string.h>
13
14 #include "tss2_sys.h"
15 #include "tss2_mu.h"
16
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "test-options.h"
20 #include "context-util.h"
21
22 void handleErrors(void)
23 {
24 unsigned long errCode;
25
26 printf("An error occurred\n");
27 while((errCode = ERR_get_error()))
28 {
29 char *err = ERR_error_string(errCode, NULL);
30 printf("%s\n", err);
31 }
32 abort();
33 }
34
35 int
36 main (int argc, char *argv[])
37 {
38 TSS2_RC rc;
39 TSS2_SYS_CONTEXT *sapi_context;
40 TSS2L_SYS_AUTH_COMMAND auth_cmd = {
41 .auths = {{ .sessionHandle = TPM2_RS_PW }},
42 .count = 1
43 };
44 TPM2B_SENSITIVE_CREATE in_sensitive = { 0 };
45 TPM2B_PUBLIC in_public = {
46 .publicArea = {
47 .type = TPM2_ALG_ECC,
48 .nameAlg = TPM2_ALG_SHA256,
49 .objectAttributes = (
50 TPMA_OBJECT_FIXEDTPM |
51 TPMA_OBJECT_FIXEDPARENT |
52 TPMA_OBJECT_SENSITIVEDATAORIGIN |
53 TPMA_OBJECT_ADMINWITHPOLICY |
54 TPMA_OBJECT_RESTRICTED |
55 TPMA_OBJECT_DECRYPT
56 ),
57 .authPolicy = {
58 .size = 32,
59 .buffer = 0x83, 0x71, 0x97, 0x67, 0x44, 0x84,
60 0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D,
61 0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52,
62 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
63 0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14,
64 0x69, 0xAA,
65 },
66 .parameters.eccDetail = {
67 .symmetric = {
68 .algorithm = TPM2_ALG_AES,
69 .keyBits.aes = 128,
70 .mode.aes = TPM2_ALG_CFB,
71 },
72 .scheme = {
73 .scheme = TPM2_ALG_NULL,
74 .details = { 0 }
75 },
76 .curveID = TPM2_ECC_NIST_P256,
77 .kdf = {.scheme = TPM2_ALG_NULL,
78 .details = { 0 }
79 }
80 },
81 .unique.ecc = {
82 .x = {.size = 32,.buffer = { 0 }},
83 .y = {.size = 32,.buffer = { 0 }}
84 }
85 }
86 };
87 TPML_PCR_SELECTION creation_pcr = { 0 };
88 TPM2_HANDLE handle;
89 TPM2B_PUBLIC out_public = { 0 };
90 TSS2L_SYS_AUTH_RESPONSE auth_rsp = {
91 .count = 0
92 };
93
94 test_opts_t opts = {
95 .tcti_type = TCTI_DEFAULT,
96 .device_file = DEVICE_PATH_DEFAULT,
97 .socket_address = HOSTNAME_DEFAULT,
98 .socket_port = PORT_DEFAULT,
99 };
100
101 get_test_opts_from_env (&opts);
102 if (sanity_check_test_opts (&opts) != 0)
103 exit (1);
104
105 sapi_context = sapi_init_from_opts (&opts);
106 if (sapi_context == NULL)
107 exit (1);
108
109 /* Generate the EK key */
110
111 rc = Tss2_Sys_CreatePrimary(sapi_context, TPM2_RH_ENDORSEMENT, &auth_cmd,
112 &in_sensitive, &in_public, NULL, &creation_pcr,
113 &handle, &out_public, NULL, NULL, NULL, NULL, &auth_rsp);
114 if (rc != TSS2_RC_SUCCESS) {
115 LOG_ERROR("TPM CreatePrimary FAILED: 0x%"PRIx32, rc);
116 exit(1);
117 }
118
119 rc = Tss2_Sys_FlushContext(sapi_context, handle);
120 if (rc != TSS2_RC_SUCCESS) {
121 LOG_ERROR("TPM FlushContext FAILED: 0x%"PRIx32, rc);
122 exit(1);
123 }
124
125 sapi_teardown_full (sapi_context);
126
127 /* Convert the key from out_public to PEM */
128
129 EVP_PKEY *evp = EVP_PKEY_new();
130
131 OpenSSL_add_all_algorithms();
132
133 OpenSSL_add_all_algorithms();
134
135 ERR_load_crypto_strings();
136
137
138 EC_KEY *ecc_key = EC_KEY_new();
139 BIGNUM *x = NULL, *y = NULL;
140 BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE);
141 int nid;
142
143 nid = EC_curve_nist2nid("P-256");
144 EC_GROUP *ecgroup = EC_GROUP_new_by_curve_name(nid);
145
146 if (!EC_KEY_set_group(ecc_key, ecgroup))
147 exit(1);
148
149 EC_KEY_set_asn1_flag(ecc_key, OPENSSL_EC_NAMED_CURVE);
150 EC_GROUP_free(ecgroup);
151
152 /* Set the ECC parameters in the OpenSSL key */
153 x = BN_bin2bn(out_public.publicArea.unique.ecc.x.buffer,
154 out_public.publicArea.unique.ecc.x.size, NULL);
155
156 y = BN_bin2bn(out_public.publicArea.unique.ecc.y.buffer,
157 out_public.publicArea.unique.ecc.y.size, NULL);
158
159 if (!x || !y) {
160 exit(1);
161 }
162
163 if (!EC_KEY_set_public_key_affine_coordinates(ecc_key, x, y)) {
164 exit(1);
165 }
166
167 if (!EVP_PKEY_assign_EC_KEY(evp, ecc_key)) {
168 handleErrors();
169 LOG_ERROR("PEM_write failed");
170 exit(1);
171 }
172
173 if (!PEM_write_bio_PUBKEY(bio, evp)) {
174 handleErrors();
175 LOG_ERROR("PEM_write failed");
176 exit(1);
177 }
178
179 BN_free(y);
180 BN_free(x);
181 EVP_PKEY_free(evp);
182 BIO_free(bio);
183
184 return 0;
185 }
0 #ifdef HAVE_CONFIG_H
1 #include <config.h>
2 #endif
3
4 #include <string.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <inttypes.h>
8
9 #include "tss2_sys.h"
10 #include "tss2_mu.h"
11
12 #define LOGMODULE test
13 #include "util/log.h"
14 #include "test-options.h"
15 #include "context-util.h"
16
17 #define TAB_SIZE(x) (sizeof(x)/sizeof(x[0]))
18
19 /* NOTE: CAP_PCRS and CAP_HANDLES->HR_PCR do not change until a reboot is
20 triggered. This should be improved if an approach is found. */
21 struct {
22 TPM2_CAP cap;
23 UINT32 prop;
24 UINT32 count;
25 } capabilities[] = {
26 { TPM2_CAP_PCRS, 0, 10 },
27 { TPM2_CAP_HANDLES, TPM2_HR_PCR, TPM2_MAX_CAP_HANDLES },
28 { TPM2_CAP_HANDLES, TPM2_HR_HMAC_SESSION, TPM2_MAX_CAP_HANDLES },
29 { TPM2_CAP_HANDLES, TPM2_HR_POLICY_SESSION, TPM2_MAX_CAP_HANDLES },
30 { TPM2_CAP_HANDLES, TPM2_HR_TRANSIENT, TPM2_MAX_CAP_HANDLES },
31 { TPM2_CAP_HANDLES, TPM2_HR_PERSISTENT, TPM2_MAX_CAP_HANDLES },
32 { TPM2_CAP_HANDLES, TPM2_HR_NV_INDEX, TPM2_MAX_CAP_HANDLES },
33 };
34
35 int
36 main (int argc, char *argv[])
37 {
38 TSS2_RC rc;
39 TSS2_SYS_CONTEXT *sapi_context;
40 TSS2L_SYS_AUTH_COMMAND auth_cmd = {
41 .auths = {{ .sessionHandle = TPM2_RS_PW }},
42 .count = 1
43 };
44 TPMI_RH_NV_INDEX nvIndex;
45
46 if (argv[1])
47 nvIndex = strtol(argv[1], NULL, 16);
48 else
49 nvIndex = 0x01c00002;
50
51 TPM2B_AUTH nv_auth = { 0 };
52 TPM2B_NV_PUBLIC public_info = {
53 .nvPublic = {
54 .nameAlg = TPM2_ALG_SHA1,
55 .attributes = TPMA_NV_PPWRITE | TPMA_NV_AUTHREAD | TPMA_NV_OWNERREAD |
56 TPMA_NV_PLATFORMCREATE | TPMA_NV_NO_DA,
57 .dataSize = 0,
58 .nvIndex = nvIndex,
59 },
60 };
61
62 TSS2L_SYS_AUTH_RESPONSE auth_rsp = {
63 .count = 0
64 };
65 TPM2B_MAX_NV_BUFFER buf1 = { 0 };
66 TPM2B_MAX_NV_BUFFER buf2 = { 0 };
67
68 buf1.size += fread(&buf1.buffer[buf1.size], sizeof(buf1.buffer[0]),
69 sizeof(buf1.buffer) - buf1.size, stdin);
70 if (buf1.size >= sizeof(buf1.buffer)) {
71 LOG_ERROR("input to large");
72 exit(1);
73 }
74
75 test_opts_t opts = {
76 .tcti_type = TCTI_DEFAULT,
77 .device_file = DEVICE_PATH_DEFAULT,
78 .socket_address = HOSTNAME_DEFAULT,
79 .socket_port = PORT_DEFAULT,
80 };
81
82 get_test_opts_from_env (&opts);
83 if (sanity_check_test_opts (&opts) != 0)
84 exit (1);
85
86 sapi_context = sapi_init_from_opts (&opts);
87 if (sapi_context == NULL)
88 exit (1);
89
90 /* First make sure that not EK certificate is currently loaded */
91 LOG_WARNING("Cert input size is %"PRIu16, buf1.size);
92 public_info.nvPublic.dataSize = buf1.size;
93
94 LOG_WARNING("Define NV cert with nv index: %x", public_info.nvPublic.nvIndex);
95
96 rc = Tss2_Sys_NV_DefineSpace(sapi_context, TPM2_RH_PLATFORM, &auth_cmd,
97 &nv_auth, &public_info, &auth_rsp);
98 if (rc != TSS2_RC_SUCCESS) {
99 LOG_ERROR("TPM NV DefineSpace FAILED: 0x%"PRIx32, rc);
100 exit(1);
101 }
102
103 /* Split the input buffer into 2 chunks */
104 buf2.size = buf1.size;
105 buf1.size /= 2;
106 buf2.size -= buf1.size;
107 memcpy(&buf2.buffer[0], &buf1.buffer[buf1.size], buf2.size);
108
109 rc = Tss2_Sys_NV_Write(sapi_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd,
110 &buf1, 0, &auth_rsp);
111 if (rc != TSS2_RC_SUCCESS) {
112 LOG_ERROR("TPM NV Write FAILED: 0x%"PRIx32, rc);
113 exit(1);
114 }
115
116 rc = Tss2_Sys_NV_Write(sapi_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd,
117 &buf2, buf1.size, &auth_rsp);
118 if (rc != TSS2_RC_SUCCESS) {
119 LOG_ERROR("TPM NV Write FAILED: 0x%"PRIx32, rc);
120 exit(1);
121 }
122
123 sapi_teardown_full (sapi_context);
124
125 return 0;
126 }
5050 ESYS_TR signHandle = ESYS_TR_NONE;
5151 ESYS_TR session = ESYS_TR_NONE;
5252 int failure_return = EXIT_FAILURE;
53
54 TPM2B_PUBLIC *outPublic = NULL;
55 TPM2B_CREATION_DATA *creationData = NULL;
56 TPM2B_DIGEST *creationHash = NULL;
57 TPMT_TK_CREATION *creationTicket = NULL;
58 TPMS_CAPABILITY_DATA *capabilityData = NULL;
59 TPM2B_ATTEST *auditInfo = NULL;
60 TPMT_SIGNATURE *signature = NULL;
5361
5462 /* Compute a signing key */
5563 TPM2B_AUTH authValuePrimary = {
127135 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
128136 goto_if_error(r, "Error: TR_SetAuth", error);
129137
130 TPM2B_PUBLIC *outPublic;
131 TPM2B_CREATION_DATA *creationData;
132 TPM2B_DIGEST *creationHash;
133 TPMT_TK_CREATION *creationTicket;
134
135138 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
136139 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
137140 &inPublic, &outsideInfo, &creationPCR,
160163 TPM2_CAP capability = TPM2_CAP_TPM_PROPERTIES;
161164 UINT32 property = TPM2_PT_LOCKOUT_COUNTER;
162165 UINT32 propertyCount = 1;
163 TPMS_CAPABILITY_DATA *capabilityData;
164166 TPMI_YES_NO moreData;
165167
166168 r = Esys_GetCapability(esys_context,
173175 ESYS_TR privacyHandle = ESYS_TR_RH_ENDORSEMENT;
174176 TPM2B_DATA qualifyingData = {0};
175177 TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL };
176 TPM2B_ATTEST *auditInfo;
177 TPMT_SIGNATURE *signature;
178178
179179 /* Test the audit commands */
180180 r = Esys_GetCommandAuditDigest(
197197 goto error;
198198 }
199199
200 Esys_Free(auditInfo);
201 Esys_Free(signature);
202
200203 goto_if_error(r, "Error: GetCommandAuditDigest", error);
201204
202205 r = Esys_GetSessionAuditDigest(
244247 r = Esys_FlushContext(esys_context, session);
245248 goto_if_error(r, "Error during FlushContext", error);
246249
250 Esys_Free(outPublic);
251 Esys_Free(creationData);
252 Esys_Free(creationHash);
253 Esys_Free(creationTicket);
254 Esys_Free(capabilityData);
255 Esys_Free(auditInfo);
256 Esys_Free(signature);
247257 return EXIT_SUCCESS;
248258
249259 error:
259269 LOG_ERROR("Cleanup signHandle failed.");
260270 }
261271 }
272 Esys_Free(outPublic);
273 Esys_Free(creationData);
274 Esys_Free(creationHash);
275 Esys_Free(creationTicket);
276 Esys_Free(capabilityData);
277 Esys_Free(auditInfo);
278 Esys_Free(signature);
262279 return failure_return;
263280 }
264281
3636 {
3737 TSS2_RC r;
3838 ESYS_TR signHandle = ESYS_TR_NONE;
39
40 TPM2B_PUBLIC *outPublic = NULL;
41 TPM2B_CREATION_DATA *creationData = NULL;
42 TPM2B_DIGEST *creationHash = NULL;
43 TPMT_TK_CREATION *creationTicket = NULL;
44 TPM2B_ATTEST *certifyInfo = NULL;
45 TPMT_SIGNATURE *signature = NULL;
3946
4047 TPM2B_AUTH authValuePrimary = {
4148 .size = 5,
116123 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
117124 goto_if_error(r, "Error: TR_SetAuth", error);
118125
119 TPM2B_PUBLIC *outPublic;
120 TPM2B_CREATION_DATA *creationData;
121 TPM2B_DIGEST *creationHash;
122 TPMT_TK_CREATION *creationTicket;
123
124126 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
125127 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
126128 &inPublic, &outsideInfo, &creationPCR,
130132
131133 TPM2B_DATA qualifyingData = {0};;
132134 TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL };;
133 TPM2B_ATTEST *certifyInfo;
134 TPMT_SIGNATURE *signature;
135135
136136 r = Esys_CertifyCreation(
137137 esys_context,
151151 r = Esys_FlushContext(esys_context,signHandle);
152152 goto_if_error(r, "Error: FlushContext", error);
153153
154 Esys_Free(certifyInfo);
155 Esys_Free(signature);
156 Esys_Free(outPublic);
157 Esys_Free(creationData);
158 Esys_Free(creationHash);
159 Esys_Free(creationTicket);
154160 return EXIT_SUCCESS;
155161
156162 error:
160166 LOG_ERROR("Cleanup signHandle failed.");
161167 }
162168 }
169 Esys_Free(certifyInfo);
170 Esys_Free(signature);
171 Esys_Free(outPublic);
172 Esys_Free(creationData);
173 Esys_Free(creationHash);
174 Esys_Free(creationTicket);
163175 return EXIT_FAILURE;
164176 }
165177
3636 {
3737 TSS2_RC r;
3838 ESYS_TR signHandle = ESYS_TR_NONE;
39
40 TPM2B_PUBLIC *outPublic = NULL;
41 TPM2B_CREATION_DATA *creationData = NULL;
42 TPM2B_DIGEST *creationHash = NULL;
43 TPMT_TK_CREATION *creationTicket = NULL;
44 TPM2B_ATTEST *certifyInfo = NULL;
45 TPMT_SIGNATURE *signature = NULL;
3946
4047 TPM2B_AUTH authValuePrimary = {
4148 .size = 5,
116123 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
117124 goto_if_error(r, "Error: TR_SetAuth", error);
118125
119 TPM2B_PUBLIC *outPublic;
120 TPM2B_CREATION_DATA *creationData;
121 TPM2B_DIGEST *creationHash;
122 TPMT_TK_CREATION *creationTicket;
123
124126 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
125127 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
126128 &inPublic, &outsideInfo, &creationPCR,
130132
131133 TPM2B_DATA qualifyingData = {0};
132134 TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL };
133 TPM2B_ATTEST *certifyInfo;
134 TPMT_SIGNATURE *signature;
135135
136136 r = Esys_Certify (
137137 esys_context,
150150 r = Esys_FlushContext(esys_context,signHandle);
151151 goto_if_error(r, "Error: FlushContext", error);
152152
153 Esys_Free(outPublic);
154 Esys_Free(creationData);
155 Esys_Free(creationHash);
156 Esys_Free(creationTicket);
157 Esys_Free(certifyInfo);
158 Esys_Free(signature);
153159 return EXIT_SUCCESS;
154160
155161 error:
159165 LOG_ERROR("Cleanup signHandle failed.");
160166 }
161167 }
168 Esys_Free(outPublic);
169 Esys_Free(creationData);
170 Esys_Free(creationHash);
171 Esys_Free(creationTicket);
172 Esys_Free(certifyInfo);
173 Esys_Free(signature);
162174 return EXIT_FAILURE;
163175 }
164176
4949 ESYS_TR_NONE,
5050 disable);
5151
52 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH) {
52 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH ||
53 (r & ~TPM2_RC_N_MASK) == TPM2_RC_HIERARCHY) {
5354 /* Platform authorization not possible test will be skipped */
5455 LOG_WARNING("Platform authorization not possible.");
5556 failure_return = EXIT_SKIP;
3838 TSS2_RC r;
3939 int failure_return = EXIT_FAILURE;
4040
41 ESYS_TR auth_handle = ESYS_TR_RH_PLATFORM;
41 ESYS_TR auth_handle = ESYS_TR_RH_OWNER;
4242 TPMS_TIME_INFO *currentTime;
4343
4444 r = Esys_ReadClock(esys_context,
1212 #include "tss2_esys.h"
1313
1414 #include "esys_iutil.h"
15 #include "test-esapi.h"
1516 #define LOGMODULE test
1617 #include "util/log.h"
1718 #include "util/aux_util.h"
2930 *
3031 * @param[in,out] esys_context The ESYS_CONTEXT.
3132 * @retval EXIT_FAILURE
33 * @retval EXIT_SKIP
3234 * @retval EXIT_SUCCESS
3335 */
3436
3840 TSS2_RC r;
3941 ESYS_TR eccHandle = ESYS_TR_NONE;
4042 ESYS_TR session = ESYS_TR_NONE;
43 int failure_return = EXIT_FAILURE;
44
45 TPM2B_PUBLIC *outPublic = NULL;
46 TPM2B_CREATION_DATA *creationData = NULL;
47 TPM2B_DIGEST *creationHash = NULL;
48 TPMT_TK_CREATION *creationTicket = NULL;
49
50 TPM2B_ECC_POINT *K = NULL;
51 TPM2B_ECC_POINT *L = NULL;
52 TPM2B_ECC_POINT *E = NULL;
53
4154 TPMT_SYM_DEF symmetric = {
4255 .algorithm = TPM2_ALG_AES,
4356 .keyBits = { .aes = 128 },
127140 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
128141 goto_if_error(r, "Error: TR_SetAuth", error);
129142
130 TPM2B_PUBLIC *outPublic;
131 TPM2B_CREATION_DATA *creationData;
132 TPM2B_DIGEST *creationHash;
133 TPMT_TK_CREATION *creationTicket;
134
135143 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, session,
136144 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic,
137145 &outsideInfo, &creationPCR, &eccHandle,
138146 &outPublic, &creationData, &creationHash,
139147 &creationTicket);
148
149 if ((r & ~TSS2_RC_LAYER_MASK) == (TPM2_RC_SCHEME | TPM2_RC_P | TPM2_RC_2)) {
150 LOG_WARNING("Scheme ECDAA not supported by TPM.");
151 failure_return = EXIT_SKIP;
152 goto error;
153 }
154
140155 goto_if_error(r, "Error esapi create primary", error);
141156
142157 TPM2B_ECC_POINT P1 = {0};
143158 TPM2B_SENSITIVE_DATA s2 = {0};
144159 TPM2B_ECC_PARAMETER y2 = {0};
145 TPM2B_ECC_POINT *K;
146 TPM2B_ECC_POINT *L;
147 TPM2B_ECC_POINT *E;
148160 UINT16 counter;
149161 r = Esys_Commit(esys_context, eccHandle,
150162 session, ESYS_TR_NONE, ESYS_TR_NONE,
162174
163175 session = ESYS_TR_NONE;
164176
177 Esys_Free(outPublic);
178 Esys_Free(creationData);
179 Esys_Free(creationHash);
180 Esys_Free(creationTicket);
181 Esys_Free(K);
182 Esys_Free(L);
183 Esys_Free(E);
165184 return EXIT_SUCCESS;
166185
167186 error:
179198 }
180199 }
181200
182 return EXIT_FAILURE;
201 Esys_Free(outPublic);
202 Esys_Free(creationData);
203 Esys_Free(creationHash);
204 Esys_Free(creationTicket);
205 Esys_Free(K);
206 Esys_Free(L);
207 Esys_Free(E);
208 return failure_return;
183209 }
184210
185211 int
4141 TSS2_RC r;
4242 ESYS_TR primaryHandle = ESYS_TR_NONE;
4343
44 TPM2B_PUBLIC *outPublic = NULL;
45 TPM2B_CREATION_DATA *creationData = NULL;
46 TPM2B_DIGEST *creationHash = NULL;
47 TPMT_TK_CREATION *creationTicket = NULL;
48 TPM2B_PUBLIC *outPublic2 = NULL;
49 TPM2B_PRIVATE *outPrivate2 = NULL;
50 TPM2B_CREATION_DATA *creationData2 = NULL;
51 TPM2B_DIGEST *creationHash2 = NULL;
52 TPMT_TK_CREATION *creationTicket2 = NULL;
53
4454 TPM2B_AUTH authValuePrimary = {
4555 .size = 5,
4656 .buffer = {1, 2, 3, 4, 5}
153163 goto_if_error(r, "Error: TR_SetAuth", error);
154164
155165 RSRC_NODE_T *primaryHandle_node;
156 TPM2B_PUBLIC *outPublic;
157 TPM2B_CREATION_DATA *creationData;
158 TPM2B_DIGEST *creationHash;
159 TPMT_TK_CREATION *creationTicket;
160166
161167 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
162168 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
175181
176182 r = Esys_TR_SetAuth(esys_context, primaryHandle, &authValuePrimary);
177183 goto_if_error(r, "Error: TR_SetAuth", error);
178
179 TPM2B_PUBLIC *outPublic2;
180 TPM2B_PRIVATE *outPrivate2;
181 TPM2B_CREATION_DATA *creationData2;
182 TPM2B_DIGEST *creationHash2;
183 TPMT_TK_CREATION *creationTicket2;
184184
185185 r = Esys_Create(esys_context,
186186 primaryHandle,
207207 r = Esys_FlushContext(esys_context, primaryHandle);
208208 goto_if_error(r, "Error during FlushContext", error);
209209
210 TPM2B_SENSITIVE_CREATE inSensitive2 = {
211 .size = 0,
212 .sensitive = {
213 .userAuth = {
214 .size = 0,
215 .buffer = {}
216 },
217 .data = {
218 .size = 0,
219 .buffer = {}
220 }
221 }
222 };
223
224 TPM2B_PUBLIC inPublic2 = {
225 .size = 0,
226 .publicArea = {
227 .type = TPM2_ALG_RSA,
228 .nameAlg = TPM2_ALG_SHA256,
229 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
230 TPMA_OBJECT_RESTRICTED |
231 TPMA_OBJECT_DECRYPT |
232 TPMA_OBJECT_FIXEDTPM |
233 TPMA_OBJECT_FIXEDPARENT |
234 TPMA_OBJECT_SENSITIVEDATAORIGIN),
235
236 .authPolicy = {
237 .size = 0,
238 },
239 .parameters.rsaDetail = {
240 .symmetric = {
241 .algorithm = TPM2_ALG_AES,
242 .keyBits.aes = 128,
243 .mode.aes = TPM2_ALG_CFB
244 },
245 .scheme = {
246 .scheme =
247 TPM2_ALG_NULL,
248 },
249 .keyBits = 2048,
250 .exponent = 0
251 },
252 .unique.rsa = {
253 .size = 0,
254 .buffer = {}
255 ,
256 }
257 }
258 };
259
260 TPM2B_DATA outsideInfo2 = {
261 .size = 0,
262 .buffer = {}
263 ,
264 };
265
266 TPML_PCR_SELECTION creationPCR2 = {
267 .count = 0,
268 };
269
270 r = Esys_Create(esys_context,
271 ESYS_TR_NONE,
272 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
273 &inSensitive2,
274 &inPublic2,
275 &outsideInfo2,
276 &creationPCR2,
277 &outPrivate2,
278 &outPublic2,
279 &creationData2, &creationHash2, &creationTicket2);
280 goto_error_if_not_failed(r, "Error esys create did not fail with bad value parameters", error);
281
282 Esys_Free(outPublic);
283 Esys_Free(creationData);
284 Esys_Free(creationHash);
285 Esys_Free(creationTicket);
210286 return EXIT_SUCCESS;
211287
212288 error:
216292 LOG_ERROR("Cleanup primaryHandle failed.");
217293 }
218294 }
295 Esys_Free(outPublic);
296 Esys_Free(creationData);
297 Esys_Free(creationHash);
298 Esys_Free(creationTicket);
219299 return EXIT_FAILURE;
220300 }
221301
4545 ESYS_TR primaryHandle = ESYS_TR_NONE;
4646 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
4747
48 TPM2B_PUBLIC *outPublic = NULL;
49 TPM2B_CREATION_DATA *creationData = NULL;
50 TPM2B_DIGEST *creationHash = NULL;
51 TPMT_TK_CREATION *creationTicket = NULL;
52
53 TPM2B_PUBLIC *outPublic2 = NULL;
54 TPM2B_PRIVATE *outPrivate2 = NULL;
55 TPM2B_CREATION_DATA *creationData2 = NULL;
56 TPM2B_DIGEST *creationHash2 = NULL;
57 TPMT_TK_CREATION *creationTicket2 = NULL;
58
4859 TPM2B_AUTH authValuePrimary = {
4960 .size = 5,
5061 .buffer = {1, 2, 3, 4, 5}
156167 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
157168 goto_if_error(r, "Error: TR_SetAuth", error);
158169
159 RSRC_NODE_T *primaryHandle_node;
160 TPM2B_PUBLIC *outPublic;
161 TPM2B_CREATION_DATA *creationData;
162 TPM2B_DIGEST *creationHash;
163 TPMT_TK_CREATION *creationTicket;
164
170 RSRC_NODE_T *primaryHandle_node = NULL;
165171 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
166172 ESYS_TR_NONE, ESYS_TR_NONE,
167173 &inSensitivePrimary, &inPublic,
261267 .count = 0,
262268 };
263269
264 TPM2B_PUBLIC *outPublic2;
265 TPM2B_PRIVATE *outPrivate2;
266 TPM2B_CREATION_DATA *creationData2;
267 TPM2B_DIGEST *creationHash2;
268 TPMT_TK_CREATION *creationTicket2;
269
270270 r = Esys_Create(esys_context,
271271 primaryHandle,
272272 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
293293 r = Esys_TR_SetAuth(esys_context, loadedKeyHandle, &authKey2);
294294 goto_if_error(r, "Error esys TR_SetAuth ", error);
295295
296 Esys_Free(outPublic2);
297 Esys_Free(outPrivate2);
298 Esys_Free(creationData2);
299 Esys_Free(creationHash2);
300 Esys_Free(creationTicket2);
301
296302 r = Esys_Create(esys_context,
297303 loadedKeyHandle,
298304 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
313319 loadedKeyHandle = ESYS_TR_NONE;
314320 goto_if_error(r, "Error during FlushContext", error);
315321
322 Esys_Free(outPublic);
323 Esys_Free(creationData);
324 Esys_Free(creationHash);
325 Esys_Free(creationTicket);
326 Esys_Free(outPublic2);
327 Esys_Free(outPrivate2);
328 Esys_Free(creationData2);
329 Esys_Free(creationHash2);
330 Esys_Free(creationTicket2);
316331 return EXIT_SUCCESS;
317332
318333 error:
329344 }
330345 }
331346
347 Esys_Free(outPublic);
348 Esys_Free(creationData);
349 Esys_Free(creationHash);
350 Esys_Free(creationTicket);
351 Esys_Free(outPublic2);
352 Esys_Free(outPrivate2);
353 Esys_Free(creationData2);
354 Esys_Free(creationHash2);
355 Esys_Free(creationTicket2);
332356 return EXIT_FAILURE;
333357 }
334358
4141 ESYS_TR primaryHandle = ESYS_TR_NONE;
4242 ESYS_TR trialHandle = ESYS_TR_NONE;
4343 ESYS_TR policyHandle = ESYS_TR_NONE;
44 TPM2B_DIGEST *trialDigest;
44
45 TPM2B_DIGEST *trialDigest = NULL;
46 TPM2B_PUBLIC *outPublic = NULL;
47 TPM2B_PUBLIC *outPublic2 = NULL;
48 TPM2B_PRIVATE *outPrivate2 = NULL;
4549
4650 TPMT_SYM_DEF policyAlgo = {
4751 .algorithm = TPM2_ALG_AES,
165169 .count = 0,
166170 };
167171
168 TPM2B_PUBLIC *outPublic;
169
170172 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
171173 ESYS_TR_NONE, ESYS_TR_NONE,
172174 &inSensitivePrimary, &inPublic,
249251 .count = 0,
250252 };
251253
252 TPM2B_PUBLIC *outPublic2;
253 TPM2B_PRIVATE *outPrivate2;
254
255254 r = Esys_Create(esys_context, primaryHandle, policyHandle, ESYS_TR_NONE,
256255 ESYS_TR_NONE, &inSensitive2, &inPublic2, &outsideInfo2,
257256 &creationPCR2, &outPrivate2, &outPublic2, NULL, NULL, NULL);
267266 primaryHandle = ESYS_TR_NONE;
268267 goto_if_error(r, "Error during FlushContext", error);
269268
269 Esys_Free(trialDigest);
270 Esys_Free(outPublic);
271 Esys_Free(outPublic2);
272 Esys_Free(outPrivate2);
270273 return EXIT_SUCCESS;
271274
272275 error:
289292 }
290293 }
291294
295 Esys_Free(trialDigest);
296 Esys_Free(outPublic);
297 Esys_Free(outPublic2);
298 Esys_Free(outPrivate2);
292299 return EXIT_FAILURE;
293300 }
294301
4040 ESYS_TR objectHandle = ESYS_TR_NONE;
4141 ESYS_TR session = ESYS_TR_NONE;
4242 TPMT_SYM_DEF symmetric = { .algorithm = TPM2_ALG_NULL };
43
44 TPM2B_PUBLIC *outPublic = NULL;
45 TPM2B_CREATION_DATA *creationData = NULL;
46 TPM2B_DIGEST *creationHash = NULL;
47 TPMT_TK_CREATION *creationTicket = NULL;
4348
4449 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
4550 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
163168 goto_if_error(r, "Error: TR_SetAuth", error);
164169
165170 RSRC_NODE_T *objectHandle_node;
166 TPM2B_PUBLIC *outPublic;
167 TPM2B_CREATION_DATA *creationData;
168 TPM2B_DIGEST *creationHash;
169 TPMT_TK_CREATION *creationTicket;
170171
171172 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, session,
172173 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic,
178179 r = esys_GetResourceObject(esys_context, objectHandle,
179180 &objectHandle_node);
180181 goto_if_error(r, "Error Esys GetResourceObject", error);
181 LOG_INFO("Created Primary with TPM handle 0x%08x...",
182 objectHandle_node->rsrc.handle);
182 ESYS_TR tpmHandle = objectHandle_node->rsrc.handle;
183 LOG_INFO("Created Primary with TPM handle 0x%08x...", tpmHandle);
183184
184185 r = Esys_FlushContext(esys_context, objectHandle);
185186 goto_if_error(r, "Error during FlushContext", error);
186187
187 LOG_INFO("Done with handle 0x%08x...", objectHandle_node->rsrc.handle);
188 LOG_INFO("Done with handle 0x%08x...", tpmHandle);
188189
189190 r = Esys_FlushContext(esys_context, session);
190191 goto_if_error(r, "Flushing context", error);
191192
193 Esys_Free(outPublic);
194 Esys_Free(creationData);
195 Esys_Free(creationHash);
196 Esys_Free(creationTicket);
192197 return EXIT_SUCCESS;
193198
194199 error:
206211 }
207212 }
208213
209
214 Esys_Free(outPublic);
215 Esys_Free(creationData);
216 Esys_Free(creationHash);
217 Esys_Free(creationTicket);
210218 return EXIT_FAILURE;
211219 }
212220
5454 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
5555 ESYS_TR primaryHandle_AuthSession = ESYS_TR_NONE;
5656 ESYS_TR session = ESYS_TR_NONE;
57 ESYS_TR outerSession = ESYS_TR_NONE;
58
59 TPM2B_PUBLIC *outPublic = NULL;
60 TPM2B_CREATION_DATA *creationData = NULL;
61 TPM2B_DIGEST *creationHash = NULL;
62 TPMT_TK_CREATION *creationTicket = NULL;
63
64 #ifdef TEST_ECC
65 TPM2B_PUBLIC *outPublicEcc = NULL;
66 TPM2B_CREATION_DATA *creationDataEcc = NULL;
67 TPM2B_DIGEST *creationHashEcc = NULL;
68 TPMT_TK_CREATION *creationTicketEcc = NULL;
69 #endif
70
71 TPM2B_PUBLIC *outPublic2 = NULL;
72 TPM2B_PRIVATE *outPrivate2 = NULL;
73 TPM2B_CREATION_DATA *creationData2 = NULL;
74 TPM2B_DIGEST *creationHash2 = NULL;
75 TPMT_TK_CREATION *creationTicket2 = NULL;
5776
5877 TPM2B_AUTH authValuePrimary = {
5978 .size = 5,
164183 goto_if_error(r, "Error: TR_SetAuth", error);
165184
166185 RSRC_NODE_T *primaryHandle_node;
167 TPM2B_PUBLIC *outPublic;
168 TPM2B_CREATION_DATA *creationData;
169 TPM2B_DIGEST *creationHash;
170 TPMT_TK_CREATION *creationTicket;
171186
172187 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
173188 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
188203
189204
190205 #ifdef TEST_ECC
191 TPM2B_PUBLIC *outPublicEcc;
192 TPM2B_CREATION_DATA *creationDataEcc;
193 TPM2B_DIGEST *creationHashEcc;
194 TPMT_TK_CREATION *creationTicketEcc;
195
196206 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
197207 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublicEcc,
198208 &outsideInfo, &creationPCR, &primaryHandle_AuthSession,
227237 TPMI_ALG_HASH authHash = TPM2_ALG_SHA256;
228238
229239 r = Esys_StartAuthSession(esys_context,
240 ESYS_TR_NONE, ESYS_TR_NONE,
241 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
242 NULL,
243 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA256,
244 &outerSession);
245 goto_if_error(r, "Error during Esys_StartAuthSession", error);
246
247 r = Esys_TRSess_SetAttributes(esys_context, outerSession, TPMA_SESSION_AUDIT,
248 TPMA_SESSION_AUDIT);
249 goto_if_error(r, "Error Esys_TRSess_SetAttributes", error);
250
251 r = Esys_StartAuthSession(esys_context,
230252 primaryHandle_AuthSession,
231253 #if TEST_BOUND_SESSION
232254 primaryHandle_AuthSession,
233255 #else
234256 ESYS_TR_NONE,
235257 #endif
236 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
258 outerSession, ESYS_TR_NONE, ESYS_TR_NONE,
237259 NULL,
238260 sessionType, &symmetric, authHash, &session);
261 Esys_FlushContext(esys_context, outerSession);
239262 goto_if_error(r, "Error during Esys_StartAuthSession", error);
240263
241264 #ifdef TEST_ECC
357380 .count = 0,
358381 };
359382
360 TPM2B_PUBLIC *outPublic2;
361 TPM2B_PRIVATE *outPrivate2;
362 TPM2B_CREATION_DATA *creationData2;
363 TPM2B_DIGEST *creationHash2;
364 TPMT_TK_CREATION *creationTicket2;
365
366383 r = Esys_Create(esys_context,
367384 primaryHandle,
368385 session, ESYS_TR_NONE, ESYS_TR_NONE,
389406 r = Esys_TR_SetAuth(esys_context, loadedKeyHandle, &authKey2);
390407 goto_if_error(r, "Error esys TR_SetAuth ", error);
391408
409 Esys_Free(outPublic2);
410 Esys_Free(outPrivate2);
411 Esys_Free(creationData2);
412 Esys_Free(creationHash2);
413 Esys_Free(creationTicket2);
414
392415 r = Esys_Create(esys_context,
393416 loadedKeyHandle,
394417 session, ESYS_TR_NONE, ESYS_TR_NONE,
410433 r = Esys_FlushContext(esys_context, session);
411434 goto_if_error(r, "Flushing context", error);
412435
436 Esys_Free(outPublic);
437 Esys_Free(creationData);
438 Esys_Free(creationHash);
439 Esys_Free(creationTicket);
440
441 #ifdef TEST_ECC
442 Esys_Free(outPublicEcc);
443 Esys_Free(creationDataEcc);
444 Esys_Free(creationHashEcc);
445 Esys_Free(creationTicketEcc);
446 #endif
447
448 Esys_Free(outPublic2);
449 Esys_Free(outPrivate2);
450 Esys_Free(creationData2);
451 Esys_Free(creationHash2);
452 Esys_Free(creationTicket2);
413453 return EXIT_SUCCESS;
414454
415455 error:
440480 }
441481 #endif
442482
443
483 Esys_Free(outPublic);
484 Esys_Free(creationData);
485 Esys_Free(creationHash);
486 Esys_Free(creationTicket);
487
488 #ifdef TEST_ECC
489 Esys_Free(outPublicEcc);
490 Esys_Free(creationDataEcc);
491 Esys_Free(creationHashEcc);
492 Esys_Free(creationTicketEcc);
493 #endif
494
495 Esys_Free(outPublic2);
496 Esys_Free(outPrivate2);
497 Esys_Free(creationData2);
498 Esys_Free(creationHash2);
499 Esys_Free(creationTicket2);
444500 return EXIT_FAILURE;
445501 }
446502
77 #include <config.h>
88 #endif
99
10 #include <stdbool.h>
1011 #include <stdlib.h>
1112
1213 #include "tss2_esys.h"
1819 #include "util/log.h"
1920 #include "util/aux_util.h"
2021
22 static bool check_name(ESYS_CONTEXT * esys_context, ESYS_TR object_handle)
23 {
24 bool result = false;
25
26 TPM2B_NAME *read_name = NULL;
27 TPM2B_NAME *get_name = NULL;
28
29 TSS2_RC r = Esys_ReadPublic(esys_context, object_handle,
30 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
31 NULL, &read_name, NULL);
32 goto_if_error(r, "Error esys readpublic", out);
33
34 r = Esys_TR_GetName(esys_context, object_handle, &get_name);
35 goto_if_error(r, "Error esys getname", out);
36
37 if (read_name->size != get_name->size) {
38 LOG_ERROR("name size mismatch %u != %u",
39 read_name->size, get_name->size);
40 goto out;
41 }
42
43 result = memcmp(read_name->name, get_name->name, get_name->size) == 0;
44
45 out:
46 Esys_Free(read_name);
47 Esys_Free(get_name);
48
49 return result;
50 }
2151 /** This test is intended to test the ESAPI command CreateLoaded.
2252 *
2353 * We start by creating a primary key (Esys_CreatePrimary).
2858 * - Esys_CreatePrimary() (M)
2959 * - Esys_FlushContext() (M)
3060 * - Esys_StartAuthSession() (M)
61 * - Esys_TR_GetName() (M)
62 * - Esys_TR_ReadPublic() (M)
3163 *
3264 * Used compiler defines: TEST_SESSION
3365 *
4577 ESYS_TR primaryHandle = ESYS_TR_NONE;
4678 ESYS_TR objectHandle = ESYS_TR_NONE;
4779 int failure_return = EXIT_FAILURE;
80
81 TPM2B_PUBLIC *outPublic = NULL;
82 TPM2B_CREATION_DATA *creationData = NULL;
83 TPM2B_DIGEST *creationHash = NULL;
84 TPMT_TK_CREATION *creationTicket = NULL;
85 TPM2B_PRIVATE *outPrivate2 = NULL;
86 TPM2B_PUBLIC *outPublic2 = NULL;
4887
4988 #ifdef TEST_SESSION
5089 ESYS_TR session = ESYS_TR_NONE;
135174 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
136175 goto_if_error(r, "Error: TR_SetAuth", error);
137176
138 TPM2B_PUBLIC *outPublic;
139 TPM2B_CREATION_DATA *creationData;
140 TPM2B_DIGEST *creationHash;
141 TPMT_TK_CREATION *creationTicket;
142
143177 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
144178 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
145179 &outsideInfo, &creationPCR, &primaryHandle,
167201 };
168202
169203 TPM2B_TEMPLATE inPublic_template = {0};
170 TPM2B_PRIVATE *outPrivate2;
171 TPM2B_PUBLIC *outPublic2;
172204 TPMT_PUBLIC inPublic2 = {
173205 .type = TPM2_ALG_ECC,
174206 .nameAlg = TPM2_ALG_SHA256,
238270
239271 goto_if_error(r, "Error During CreateLoaded", error);
240272
273 bool names_match = check_name(esys_context, objectHandle);
274 if (!names_match) {
275 goto error;
276 }
277
241278 r = Esys_FlushContext(esys_context, primaryHandle);
242279 goto_if_error(r, "Flushing context", error);
243280
253290 goto_if_error(r, "Error: FlushContext", error);
254291 #endif
255292
293 SAFE_FREE(outPublic);
294 SAFE_FREE(creationData);
295 SAFE_FREE(creationHash);
296 SAFE_FREE(creationTicket);
297 SAFE_FREE(outPrivate2);
298 SAFE_FREE(outPublic2);
256299 return EXIT_SUCCESS;
257300
258301 error:
277320 }
278321 }
279322
323 SAFE_FREE(outPublic);
324 SAFE_FREE(creationData);
325 SAFE_FREE(creationHash);
326 SAFE_FREE(creationTicket);
327 SAFE_FREE(outPrivate2);
328 SAFE_FREE(outPublic2);
280329 return failure_return;
281330 }
282331
5555 ESYS_TR policySession = ESYS_TR_NONE;
5656 int failure_return = EXIT_FAILURE;
5757
58 TPM2B_DIGEST *policyDigestTrial = NULL;
59 TPM2B_PUBLIC *outPublic = NULL;
60 TPM2B_CREATION_DATA *creationData = NULL;
61 TPM2B_DIGEST *creationHash = NULL;
62 TPMT_TK_CREATION *creationTicket = NULL;
63
64 TPM2B_PUBLIC *outPublic2 = NULL;
65 TPM2B_PRIVATE *outPrivate2 = NULL;
66 TPM2B_CREATION_DATA *creationData2 = NULL;
67 TPM2B_DIGEST *creationHash2 = NULL;
68 TPMT_TK_CREATION *creationTicket2 = NULL;
69
70 TPM2B_PUBLIC *keyPublic = NULL;
71 TPM2B_NAME *keyName = NULL;
72 TPM2B_NAME *keyQualifiedName = NULL;
73
74 TPM2B_DATA *encryptionKeyOut = NULL;
75 TPM2B_PRIVATE *duplicate = NULL;
76 TPM2B_ENCRYPTED_SECRET *outSymSeed = NULL;
77
78 TPM2B_PRIVATE *outDuplicate = NULL;
79 TPM2B_ENCRYPTED_SECRET *outSymSeed2 = NULL;
80
5881 /*
5982 * First the policy value to be able to use Esys_Duplicate for an object has to be
6083 * determined with a policy trial session.
94117 );
95118 goto_if_error(r, "Error: PolicyCommandCode", error);
96119
97 TPM2B_DIGEST *policyDigestTrial;
98120 r = Esys_PolicyGetDigest(esys_context,
99121 sessionTrial,
100122 ESYS_TR_NONE,
175197 goto_if_error(r, "Error: TR_SetAuth", error);
176198
177199 RSRC_NODE_T *primaryHandle_node;
178 TPM2B_PUBLIC *outPublic;
179 TPM2B_CREATION_DATA *creationData;
180 TPM2B_DIGEST *creationHash;
181 TPMT_TK_CREATION *creationTicket;
182200
183201 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
184202 ESYS_TR_NONE, ESYS_TR_NONE,
187205 &outPublic, &creationData, &creationHash,
188206 &creationTicket);
189207 goto_if_error(r, "Error esys create primary", error);
208
209 Esys_Free(outPublic);
210 Esys_Free(creationData);
211 Esys_Free(creationHash);
212 Esys_Free(creationTicket);
190213
191214 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
192215 ESYS_TR_NONE, ESYS_TR_NONE,
271294 .count = 0,
272295 };
273296
274 TPM2B_PUBLIC *outPublic2;
275 TPM2B_PRIVATE *outPrivate2;
276 TPM2B_CREATION_DATA *creationData2;
277 TPM2B_DIGEST *creationHash2;
278 TPMT_TK_CREATION *creationTicket2;
279
280297 inPublic2.publicArea.authPolicy = *policyDigestTrial;
281298
282299 r = Esys_Create(esys_context,
305322 r = Esys_TR_SetAuth(esys_context, loadedKeyHandle, &authKey2);
306323 goto_if_error(r, "Error esys TR_SetAuth ", error);
307324
308 TPM2B_PUBLIC *keyPublic;
309 TPM2B_NAME *keyName;
310 TPM2B_NAME *keyQualifiedName;
311
312325 r = Esys_ReadPublic(esys_context,
313326 loadedKeyHandle,
314327 ESYS_TR_NONE,
364377 TPMT_SYM_DEF_OBJECT symmetric = {.algorithm = TPM2_ALG_AES,
365378 .keyBits = {.aes = 128},
366379 .mode = {.aes = TPM2_ALG_CFB}};
367
368 TPM2B_DATA *encryptionKeyOut;
369 TPM2B_PRIVATE *duplicate;
370 TPM2B_ENCRYPTED_SECRET *outSymSeed;
371380
372381 r = Esys_Duplicate(
373382 esys_context,
384393
385394 goto_if_error(r, "Error: Duplicate", error);
386395
387 TPM2B_PRIVATE *outDuplicate;
388 TPM2B_ENCRYPTED_SECRET *outSymSeed2;
389
390396 r = Esys_Rewrap(esys_context,
391397 primaryHandle2,
392398 primaryHandle,
428434 r = Esys_FlushContext(esys_context, policySession);
429435 goto_if_error(r, "Flushing context", error);
430436
431
437 Esys_Free(policyDigestTrial);
438 Esys_Free(outPublic);
439 Esys_Free(creationData);
440 Esys_Free(creationHash);
441 Esys_Free(creationTicket);
442 Esys_Free(outPublic2);
443 Esys_Free(outPrivate2);
444 Esys_Free(creationData2);
445 Esys_Free(creationHash2);
446 Esys_Free(creationTicket2);
447 Esys_Free(keyPublic);
448 Esys_Free(keyName);
449 Esys_Free(keyQualifiedName);
450 Esys_Free(encryptionKeyOut);
451 Esys_Free(duplicate);
452 Esys_Free(outSymSeed);
453 Esys_Free(outDuplicate);
454 Esys_Free(outSymSeed2);
432455 return EXIT_SUCCESS;
433456
434457 error:
463486 }
464487 }
465488
489 Esys_Free(policyDigestTrial);
490 Esys_Free(outPublic);
491 Esys_Free(creationData);
492 Esys_Free(creationHash);
493 Esys_Free(creationTicket);
494 Esys_Free(outPublic2);
495 Esys_Free(outPrivate2);
496 Esys_Free(creationData2);
497 Esys_Free(creationHash2);
498 Esys_Free(creationTicket2);
499 Esys_Free(keyPublic);
500 Esys_Free(keyName);
501 Esys_Free(keyQualifiedName);
502 Esys_Free(encryptionKeyOut);
503 Esys_Free(duplicate);
504 Esys_Free(outSymSeed);
505 Esys_Free(outDuplicate);
506 Esys_Free(outSymSeed2);
466507 return failure_return;
467508 }
468509
4545 .size = 20,
4646 .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
4747 };
48
49 TPM2B_PUBLIC *outPublic = NULL;
50 TPM2B_CREATION_DATA *creationData = NULL;
51 TPM2B_DIGEST *creationHash = NULL;
52 TPMT_TK_CREATION *creationTicket = NULL;
53
54 TPM2B_ECC_POINT *zPoint = NULL;
55 TPM2B_ECC_POINT *pubPoint = NULL;
4856
4957 memset(&sessionAttributes, 0, sizeof sessionAttributes);
5058
123131 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
124132 goto_if_error(r, "Error: TR_SetAuth", error);
125133
126 TPM2B_PUBLIC *outPublic;
127 TPM2B_CREATION_DATA *creationData;
128 TPM2B_DIGEST *creationHash;
129 TPMT_TK_CREATION *creationTicket;
130
131134 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, session,
132135 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic,
133136 &outsideInfo, &creationPCR, &eccHandle,
134137 &outPublic, &creationData, &creationHash,
135138 &creationTicket);
136139 goto_if_error(r, "Error esapi create primary", error);
137
138 TPM2B_ECC_POINT *zPoint;
139 TPM2B_ECC_POINT *pubPoint;
140140
141141 r = Esys_ECDH_KeyGen(
142142 esys_context,
154154 r = Esys_FlushContext(esys_context, session);
155155 goto_if_error(r, "Flushing context", error);
156156
157 Esys_Free(outPublic);
158 Esys_Free(creationData);
159 Esys_Free(creationHash);
160 Esys_Free(creationTicket);
161
162 Esys_Free(zPoint);
163 Esys_Free(pubPoint);
157164 return EXIT_SUCCESS;
158165
159166 error:
170177 LOG_ERROR("Cleanup eccHandle failed.");
171178 }
172179 }
180 Esys_Free(outPublic);
181 Esys_Free(creationData);
182 Esys_Free(creationHash);
183 Esys_Free(creationTicket);
184
185 Esys_Free(zPoint);
186 Esys_Free(pubPoint);
173187 return EXIT_FAILURE;
174188 }
175189
4848 .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
4949 };
5050
51 TPM2B_PUBLIC *outPublic = NULL;
52 TPM2B_CREATION_DATA *creationData = NULL;
53 TPM2B_DIGEST *creationHash = NULL;
54 TPMT_TK_CREATION *creationTicket = NULL;
55 TPM2B_ECC_POINT *outPoint = NULL;
56
5157 memset(&sessionAttributes, 0, sizeof sessionAttributes);
5258
5359 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
125131 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
126132 goto_if_error(r, "Error: TR_SetAuth", error);
127133
128 TPM2B_PUBLIC *outPublic;
129 TPM2B_CREATION_DATA *creationData;
130 TPM2B_DIGEST *creationHash;
131 TPMT_TK_CREATION *creationTicket;
132
133134 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, session,
134135 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic,
135136 &outsideInfo, &creationPCR, &eccHandle,
161162 }
162163 };
163164
164 TPM2B_ECC_POINT *outPoint;
165165 r = Esys_ECDH_ZGen(
166166 esys_context,
167167 eccHandle,
178178 r = Esys_FlushContext(esys_context, session);
179179 goto_if_error(r, "Flushing context", error);
180180
181 Esys_Free(outPublic);
182 Esys_Free(creationData);
183 Esys_Free(creationHash);
184 Esys_Free(creationTicket);
185 Esys_Free(outPoint);
181186 return EXIT_SUCCESS;
182187
183188 error:
195200 }
196201 }
197202
203 Esys_Free(outPublic);
204 Esys_Free(creationData);
205 Esys_Free(creationHash);
206 Esys_Free(creationTicket);
207 Esys_Free(outPoint);
198208 return EXIT_FAILURE;
199209 }
200210
4444 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
4545 int failure_return = EXIT_FAILURE;
4646
47 TPM2B_PUBLIC *outPublic = NULL;
48 TPM2B_CREATION_DATA *creationData = NULL;
49 TPM2B_DIGEST *creationHash = NULL;
50 TPMT_TK_CREATION *creationTicket = NULL;
51 TPM2B_MAX_BUFFER *outData = NULL;
52 TPM2B_IV *ivOut = NULL;
53
54 TPM2B_PUBLIC *outPublic2 = NULL;
55 TPM2B_PRIVATE *outPrivate2 = NULL;
56 TPM2B_CREATION_DATA *creationData2 = NULL;
57 TPM2B_DIGEST *creationHash2 = NULL;
58 TPMT_TK_CREATION *creationTicket2 = NULL;
59 TPM2B_MAX_BUFFER *outData2 = NULL;
60 TPM2B_IV *ivOut2 = NULL;
4761
4862 TPM2B_AUTH authValuePrimary = {
4963 .size = 5,
115129 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
116130 goto_if_error(r, "Error: TR_SetAuth", error);
117131
118 TPM2B_PUBLIC *outPublic;
119 TPM2B_CREATION_DATA *creationData;
120 TPM2B_DIGEST *creationHash;
121 TPMT_TK_CREATION *creationTicket;
122
123132 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
124133 ESYS_TR_NONE, ESYS_TR_NONE,
125134 &inSensitivePrimary, &inPublic,
186195 TPML_PCR_SELECTION creationPCR2 = {
187196 .count = 0,
188197 };
189
190 TPM2B_PUBLIC *outPublic2;
191 TPM2B_PRIVATE *outPrivate2;
192 TPM2B_CREATION_DATA *creationData2;
193 TPM2B_DIGEST *creationHash2;
194 TPMT_TK_CREATION *creationTicket2;
195198
196199 r = Esys_Create(esys_context,
197200 primaryHandle,
203206 &outPrivate2,
204207 &outPublic2,
205208 &creationData2, &creationHash2, &creationTicket2);
209
210 if (r == 0x2c2) { /*<< tpm:parameter(2):inconsistent attributes */
211 LOG_WARNING("Unsupported symmetric cipher.");
212 failure_return = EXIT_SKIP;
213 goto error;
214 }
206215 goto_if_error(r, "Error esys create ", error);
207216
208217 LOG_INFO("AES key created.");
231240 .size = 16,
232241 .buffer = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16}
233242 };
234 TPM2B_MAX_BUFFER *outData;
235 TPM2B_IV *ivOut;
236243
237244 r = Esys_EncryptDecrypt(
238245 esys_context,
257264
258265 goto_if_error(r, "Error: EncryptDecrypt", error);
259266
260 TPM2B_MAX_BUFFER *outData2;
261 TPM2B_IV *ivOut2;
262267
263268 r = Esys_EncryptDecrypt(
264269 esys_context,
299304 r = Esys_FlushContext(esys_context, loadedKeyHandle);
300305 goto_if_error(r, "Error during FlushContext", error);
301306
307 Esys_Free(outPublic);
308 Esys_Free(creationData);
309 Esys_Free(creationHash);
310 Esys_Free(creationTicket);
311 Esys_Free(outData);
312 Esys_Free(ivOut);
313
314 Esys_Free(outPublic2);
315 Esys_Free(outPrivate2);
316 Esys_Free(creationData2);
317 Esys_Free(creationHash2);
318 Esys_Free(creationTicket2);
319 Esys_Free(outData2);
320 Esys_Free(ivOut2);
302321 return EXIT_SUCCESS;
303322
304323 error:
314333 LOG_ERROR("Cleanup loadedKeyHandle failed.");
315334 }
316335 }
336 Esys_Free(outPublic);
337 Esys_Free(creationData);
338 Esys_Free(creationHash);
339 Esys_Free(creationTicket);
340 Esys_Free(outData);
341 Esys_Free(ivOut);
342
343 Esys_Free(outPublic2);
344 Esys_Free(outPrivate2);
345 Esys_Free(creationData2);
346 Esys_Free(creationHash2);
347 Esys_Free(creationTicket2);
348 Esys_Free(outData2);
349 Esys_Free(ivOut2);
317350 return failure_return;
318351 }
319352
4040
4141 TPMI_ALG_HASH hashAlg = TPM2_ALG_NULL; /**< enforce event Sequence */
4242 ESYS_TR sequenceHandle_handle;
43 TPML_DIGEST_VALUES *results = NULL;
4344
4445 r = Esys_HashSequenceStart(esys_context,
4546 ESYS_TR_NONE,
6970
7071 ESYS_TR pcrHandle_handle = 16;
7172
72 TPML_DIGEST_VALUES *results;
7373 r = Esys_EventSequenceComplete (
7474 esys_context,
7575 pcrHandle_handle,
8181 &results);
8282 goto_if_error(r, "Error: EventSequenceComplete", error);
8383
84 Esys_Free(results);
8485 return EXIT_SUCCESS;
8586
8687 error:
88 Esys_Free(results);
8789 return EXIT_FAILURE;
8890 }
8991
4343 ESYS_TR primaryHandle = ESYS_TR_NONE;
4444 ESYS_TR persistent_handle1 = ESYS_TR_NONE;
4545
46 TPM2B_PUBLIC *outPublic = NULL;
47 TPM2B_CREATION_DATA *creationData = NULL;
48 TPM2B_DIGEST *creationHash = NULL;
49 TPMT_TK_CREATION *creationTicket = NULL;
50 TPM2B_PUBLIC *outPublic2 = NULL;
51 TPM2B_PRIVATE *outPrivate2 = NULL;
52 TPM2B_CREATION_DATA *creationData2 = NULL;
53 TPM2B_DIGEST *creationHash2 = NULL;
54 TPMT_TK_CREATION *creationTicket2 = NULL;
55
4656 TPM2B_AUTH authValuePrimary = {
4757 .size = 5,
4858 .buffer = {1, 2, 3, 4, 5}
115125 goto_if_error(r, "Error: TR_SetAuth", error);
116126
117127 RSRC_NODE_T *primaryHandle_node;
118 TPM2B_PUBLIC *outPublic;
119 TPM2B_CREATION_DATA *creationData;
120 TPM2B_DIGEST *creationHash;
121 TPMT_TK_CREATION *creationTicket;
122128
123129 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
124130 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
223229 .count = 0,
224230 };
225231
226 TPM2B_PUBLIC *outPublic2;
227 TPM2B_PRIVATE *outPrivate2;
228 TPM2B_CREATION_DATA *creationData2;
229 TPM2B_DIGEST *creationHash2;
230 TPMT_TK_CREATION *creationTicket2;
231
232232 r = Esys_TR_SetAuth(esys_context, persistent_handle2, &authValuePrimary);
233233 goto_if_error(r, "Error: TR_SetAuth", error);
234234
253253 permanentHandle, &persistent_handle1);
254254 goto_if_error(r, "Error Esys EvictControl", error);
255255
256 Esys_Free(outPublic);
257 Esys_Free(creationData);
258 Esys_Free(creationHash);
259 Esys_Free(creationTicket);
260 Esys_Free(outPublic2);
261 Esys_Free(outPrivate2);
262 Esys_Free(creationData2);
263 Esys_Free(creationHash2);
264 Esys_Free(creationTicket2);
256265 return EXIT_SUCCESS;
257266
258267 error:
272281 }
273282 }
274283
284 Esys_Free(outPublic);
285 Esys_Free(creationData);
286 Esys_Free(creationHash);
287 Esys_Free(creationTicket);
288 Esys_Free(outPublic2);
289 Esys_Free(outPrivate2);
290 Esys_Free(creationData2);
291 Esys_Free(creationHash2);
292 Esys_Free(creationTicket2);
275293 return EXIT_FAILURE;
276294 }
277295
4242
4343 LOGBLOB_DEBUG(&randomBytes->buffer[0], randomBytes->size,
4444 "Randoms (count=%i):", randomBytes->size);
45 free(randomBytes);
45 Esys_Free(randomBytes);
4646
4747 LOG_INFO("GetRandom Test Passed!");
4848
6464 }
6565
6666 r = Esys_TRSess_SetAttributes(esys_context, session, TPMA_SESSION_AUDIT,
67 TPMA_SESSION_AUDIT);
67 TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_AUDIT);
68 if (r != TPM2_RC_SUCCESS) {
69 LOG_ERROR("SetAttributes on session FAILED! Response Code : 0x%x", r);
70 goto error_cleansession;
71 }
72
73 r = Esys_GetRandom(esys_context, session, ESYS_TR_NONE, ESYS_TR_NONE, 48,
74 &randomBytes);
75 if (r != TPM2_RC_SUCCESS) {
76 LOG_ERROR("GetRandom with session FAILED! Response Code : 0x%x", r);
77 goto error_cleansession;
78 }
79
80 LOGBLOB_DEBUG(&randomBytes->buffer[0], randomBytes->size,
81 "Randoms (count=%i):", randomBytes->size);
82 free(randomBytes);
83
84 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
85 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
86 NULL,
87 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
88 &session);
89 if (r != TPM2_RC_SUCCESS) {
90 LOG_ERROR("Esys_StartAuthSession FAILED! Response Code : 0x%x", r);
91 goto error;
92 }
93
94 r = Esys_TRSess_SetAttributes(esys_context, session, TPMA_SESSION_AUDIT,
95 TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_AUDIT);
96 if (r != TPM2_RC_SUCCESS) {
97 LOG_ERROR("SetAttributes on session FAILED! Response Code : 0x%x", r);
98 goto error_cleansession;
99 }
100
101 r = Esys_GetRandom(esys_context, session, ESYS_TR_NONE, ESYS_TR_NONE, 48,
102 &randomBytes);
103 if (r != TPM2_RC_SUCCESS) {
104 LOG_ERROR("GetRandom with session FAILED! Response Code : 0x%x", r);
105 goto error_cleansession;
106 }
107
108 LOGBLOB_DEBUG(&randomBytes->buffer[0], randomBytes->size,
109 "Randoms (count=%i):", randomBytes->size);
110 free(randomBytes);
111
112 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
113 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
114 NULL,
115 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
116 &session);
117 if (r != TPM2_RC_SUCCESS) {
118 LOG_ERROR("Esys_StartAuthSession FAILED! Response Code : 0x%x", r);
119 goto error;
120 }
121
122 r = Esys_TRSess_SetAttributes(esys_context, session, TPMA_SESSION_AUDIT,
123 TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_AUDIT);
124 if (r != TPM2_RC_SUCCESS) {
125 LOG_ERROR("SetAttributes on session FAILED! Response Code : 0x%x", r);
126 goto error_cleansession;
127 }
128
129 r = Esys_GetRandom(esys_context, session, ESYS_TR_NONE, ESYS_TR_NONE, 48,
130 &randomBytes);
131 if (r != TPM2_RC_SUCCESS) {
132 LOG_ERROR("GetRandom with session FAILED! Response Code : 0x%x", r);
133 goto error_cleansession;
134 }
135
136 LOGBLOB_DEBUG(&randomBytes->buffer[0], randomBytes->size,
137 "Randoms (count=%i):", randomBytes->size);
138 free(randomBytes);
139
140 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
141 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
142 NULL,
143 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
144 &session);
145 if (r != TPM2_RC_SUCCESS) {
146 LOG_ERROR("Esys_StartAuthSession FAILED! Response Code : 0x%x", r);
147 goto error;
148 }
149
150 r = Esys_TRSess_SetAttributes(esys_context, session, TPMA_SESSION_AUDIT,
151 TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_AUDIT);
152 if (r != TPM2_RC_SUCCESS) {
153 LOG_ERROR("SetAttributes on session FAILED! Response Code : 0x%x", r);
154 goto error_cleansession;
155 }
156
157 r = Esys_GetRandom(esys_context, session, ESYS_TR_NONE, ESYS_TR_NONE, 48,
158 &randomBytes);
159 if (r != TPM2_RC_SUCCESS) {
160 LOG_ERROR("GetRandom with session FAILED! Response Code : 0x%x", r);
161 goto error_cleansession;
162 }
163
164 LOGBLOB_DEBUG(&randomBytes->buffer[0], randomBytes->size,
165 "Randoms (count=%i):", randomBytes->size);
166 free(randomBytes);
167
168 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
169 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
170 NULL,
171 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
172 &session);
173 if (r != TPM2_RC_SUCCESS) {
174 LOG_ERROR("Esys_StartAuthSession FAILED! Response Code : 0x%x", r);
175 goto error;
176 }
177
178 r = Esys_TRSess_SetAttributes(esys_context, session, TPMA_SESSION_AUDIT,
179 TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_AUDIT);
68180 if (r != TPM2_RC_SUCCESS) {
69181 LOG_ERROR("SetAttributes on session FAILED! Response Code : 0x%x", r);
70182 goto error_cleansession;
83195
84196 LOG_INFO("GetRandom with session Test Passed!");
85197
86 r = Esys_FlushContext(esys_context, session);
198 //r = Esys_FlushContext(esys_context, session);
87199 if (r != TPM2_RC_SUCCESS) {
88200 LOG_ERROR("FlushContext with session FAILED! Response Code : 0x%x", r);
89201 goto error_cleansession;
4040 TSS2_RC r;
4141 ESYS_TR signHandle = ESYS_TR_NONE;
4242 int failure_return = EXIT_FAILURE;
43
44 TPM2B_PUBLIC *outPublic = NULL;
45 TPM2B_CREATION_DATA *creationData = NULL;
46 TPM2B_DIGEST *creationHash = NULL;
47 TPMT_TK_CREATION *creationTicket = NULL;
48 TPM2B_ATTEST *timeInfo = NULL;
49 TPMT_SIGNATURE *signature = NULL;
4350
4451 TPM2B_AUTH authValuePrimary = {
4552 .size = 5,
121128 goto_if_error(r, "Error: TR_SetAuth", error);
122129
123130 RSRC_NODE_T *primaryHandle_node;
124 TPM2B_PUBLIC *outPublic;
125 TPM2B_CREATION_DATA *creationData;
126 TPM2B_DIGEST *creationHash;
127 TPMT_TK_CREATION *creationTicket;
128131
129132 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
130133 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
147150 ESYS_TR privacyAdminHandle= ESYS_TR_RH_ENDORSEMENT;
148151 TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL };
149152 TPM2B_DATA qualifyingData = {0};
150 TPM2B_ATTEST *timeInfo;
151 TPMT_SIGNATURE *signature;
152153
153154 r = Esys_GetTime (
154155 esys_context,
177178 r = Esys_FlushContext(esys_context, signHandle);
178179 goto_if_error(r, "Error: FlushContext", error);
179180
181 Esys_Free(outPublic);
182 Esys_Free(creationData);
183 Esys_Free(creationHash);
184 Esys_Free(creationTicket);
185 Esys_Free(timeInfo);
186 Esys_Free(signature);
180187 return EXIT_SUCCESS;
181188
182189 error:
186193 LOG_ERROR("Cleanup signHandle failed.");
187194 }
188195 }
196 Esys_Free(outPublic);
197 Esys_Free(creationData);
198 Esys_Free(creationHash);
199 Esys_Free(creationTicket);
200 Esys_Free(timeInfo);
201 Esys_Free(signature);
189202 return failure_return;
190203 }
191204
3737 1, 2, 3, 4, 5, 6, 7, 8, 9}};
3838 TPMI_ALG_HASH hashAlg = TPM2_ALG_SHA1;
3939 TPMI_RH_HIERARCHY hierarchy = TPM2_RH_OWNER;
40 TPM2B_DIGEST *outHash;
41 TPMT_TK_HASHCHECK *validation;
40 TPM2B_DIGEST *outHash = NULL;
41 TPMT_TK_HASHCHECK *validation = NULL;
4242
4343 r = Esys_Hash(
4444 esys_context,
5252 &validation);
5353 goto_if_error(r, "Error: Hash", error);
5454
55 Esys_Free(outHash);
56 Esys_Free(validation);
5557 return EXIT_SUCCESS;
5658
5759 error:
60 Esys_Free(outHash);
61 Esys_Free(validation);
5862 return EXIT_FAILURE;
5963 }
6064
3737 test_esys_hashsequencestart(ESYS_CONTEXT * esys_context)
3838 {
3939 TSS2_RC r;
40
41 TPM2B_DIGEST *result = NULL;
42 TPMT_TK_HASHCHECK *validation = NULL;
4043
4144 #ifdef TEST_SESSION
4245 ESYS_TR session = ESYS_TR_NONE;
98101 );
99102 goto_if_error(r, "Error: SequenceUpdate", error);
100103
101 TPM2B_DIGEST *result;
102 TPMT_TK_HASHCHECK *validation;
103
104104 r = Esys_SequenceComplete(esys_context,
105105 sequenceHandle_handle,
106106 #ifdef TEST_SESSION
122122 goto_if_error(r, "Error: FlushContext", error);
123123 #endif
124124
125 Esys_Free(result);
126 Esys_Free(validation);
125127 return EXIT_SUCCESS;
126128
127129 error:
133135 }
134136 }
135137 #endif
138 Esys_Free(result);
139 Esys_Free(validation);
136140 return EXIT_FAILURE;
137141 }
138142
4444 TPMI_YES_NO state = TPM2_NO;
4545 ESYS_TR primaryHandle = ESYS_TR_NONE;
4646 int failure_return = EXIT_FAILURE;
47
48 TPM2B_PUBLIC *outPublic = NULL;
49 TPM2B_CREATION_DATA *creationData = NULL;
50 TPM2B_DIGEST *creationHash = NULL;
51 TPMT_TK_CREATION *creationTicket = NULL;
4752
4853 r = Esys_HierarchyControl(
4954 esys_context,
120125
121126 goto_if_error(r, "Error: TR_SetAuth", error);
122127
123 TPM2B_PUBLIC *outPublic;
124 TPM2B_CREATION_DATA *creationData;
125 TPM2B_DIGEST *creationHash;
126 TPMT_TK_CREATION *creationTicket;
127
128128 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
129129 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
130130 &outsideInfo, &creationPCR, &primaryHandle,
155155 r = Esys_FlushContext(esys_context, primaryHandle);
156156 goto_if_error(r, "Error: FlushContext", error);
157157
158 Esys_Free(outPublic);
159 Esys_Free(creationData);
160 Esys_Free(creationHash);
161 Esys_Free(creationTicket);
158162 return EXIT_SUCCESS;
159163
160164 error:
165169 }
166170 }
167171
172 Esys_Free(outPublic);
173 Esys_Free(creationData);
174 Esys_Free(creationHash);
175 Esys_Free(creationTicket);
168176 return failure_return;
169177 }
170178
4141 ESYS_TR primaryHandle = ESYS_TR_NONE;
4242 bool auth_changed = false;
4343 ESYS_TR authHandle_handle = ESYS_TR_RH_OWNER;
44
45 TPM2B_PUBLIC *outPublic = NULL;
46 TPM2B_CREATION_DATA *creationData = NULL;
47 TPM2B_DIGEST *creationHash = NULL;
48 TPMT_TK_CREATION *creationTicket = NULL;
49
4450 TPM2B_AUTH newAuth = {
4551 .size = 5,
4652 .buffer = {1, 2, 3, 4, 5}
119125
120126 goto_if_error(r, "Error: TR_SetAuth", error);
121127
122 TPM2B_PUBLIC *outPublic;
123 TPM2B_CREATION_DATA *creationData;
124 TPM2B_DIGEST *creationHash;
125 TPMT_TK_CREATION *creationTicket;
126
127128 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
128129 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
129130 &outsideInfo, &creationPCR, &primaryHandle,
139140 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &newAuth);
140141 goto_if_error(r, "Error SetAuth", error);
141142
143 Esys_Free(outPublic);
144 Esys_Free(creationData);
145 Esys_Free(creationHash);
146 Esys_Free(creationTicket);
147
142148 /* Check whether HierarchyChangeAuth with auth equal NULL works */
143149
144150 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
159165 NULL);
160166 goto_if_error(r, "Error: HierarchyChangeAuth", error);
161167
168 Esys_Free(outPublic);
169 Esys_Free(creationData);
170 Esys_Free(creationHash);
171 Esys_Free(creationTicket);
162172 return EXIT_SUCCESS;
163173
164174 error:
183193 }
184194 }
185195
196 Esys_Free(outPublic);
197 Esys_Free(creationData);
198 Esys_Free(creationHash);
199 Esys_Free(creationTicket);
186200 return EXIT_FAILURE;
187201 }
188202
3939 TSS2_RC r;
4040 ESYS_TR primaryHandle = ESYS_TR_NONE;
4141
42 TPM2B_PUBLIC *outPublic = NULL;
43 TPM2B_CREATION_DATA *creationData = NULL;
44 TPM2B_DIGEST *creationHash = NULL;
45 TPMT_TK_CREATION *creationTicket = NULL;
46 TPM2B_DIGEST *outHMAC = NULL;
47
4248 TPM2B_AUTH authValuePrimary = {
4349 .size = 5,
4450 .buffer = {1, 2, 3, 4, 5}
6874 .count = 0,
6975 };
7076
71 TPM2B_PUBLIC *outPublic;
72 TPM2B_CREATION_DATA *creationData;
73 TPM2B_DIGEST *creationHash;
74 TPMT_TK_CREATION *creationTicket;
75
7677 inPublic.publicArea.nameAlg = TPM2_ALG_SHA1;
7778 inPublic.publicArea.type = TPM2_ALG_KEYEDHASH;
7879 inPublic.publicArea.objectAttributes |= TPMA_OBJECT_SIGN_ENCRYPT;
9495 TPM2B_MAX_BUFFER test_buffer = { .size = 20,
9596 .buffer={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
9697 1, 2, 3, 4, 5, 6, 7, 8, 9}} ;
97 TPM2B_DIGEST *outHMAC;
98
9998 r = Esys_HMAC(
10099 esys_context,
101100 primaryHandle,
110109 r = Esys_FlushContext(esys_context, primaryHandle);
111110 goto_if_error(r, "Error: FlushContext", error);
112111
112 Esys_Free(outPublic);
113 Esys_Free(creationData);
114 Esys_Free(creationHash);
115 Esys_Free(creationTicket);
116 Esys_Free(outHMAC);
113117 return EXIT_SUCCESS;
114118
115119 error:
120124 }
121125 }
122126
127 Esys_Free(outPublic);
128 Esys_Free(creationData);
129 Esys_Free(creationHash);
130 Esys_Free(creationTicket);
131 Esys_Free(outHMAC);
123132 return EXIT_FAILURE;
124133 }
125134
4040 {
4141 TSS2_RC r;
4242 ESYS_TR primaryHandle = ESYS_TR_NONE;
43
44 TPM2B_PUBLIC *outPublic = NULL;
45 TPM2B_CREATION_DATA *creationData = NULL;
46 TPM2B_DIGEST *creationHash = NULL;
47 TPMT_TK_CREATION *creationTicket = NULL;
48
49 TPM2B_DIGEST *result = NULL;
50 TPMT_TK_HASHCHECK *validation = NULL;
4351
4452 #ifdef TEST_SESSION
4553 ESYS_TR session = ESYS_TR_NONE;
94102 .count = 0,
95103 };
96104
97 TPM2B_PUBLIC *outPublic;
98 TPM2B_CREATION_DATA *creationData;
99 TPM2B_DIGEST *creationHash;
100 TPMT_TK_CREATION *creationTicket;
101
102105 inPublic.publicArea.nameAlg = TPM2_ALG_SHA1;
103106 inPublic.publicArea.type = TPM2_ALG_KEYEDHASH;
104107 inPublic.publicArea.objectAttributes |= TPMA_OBJECT_SIGN_ENCRYPT;
158161 );
159162 goto_if_error(r, "Error: SequenceUpdate", error);
160163
161 TPM2B_DIGEST *result;
162 TPMT_TK_HASHCHECK *validation;
163
164164 r = Esys_SequenceComplete(esys_context,
165165 sequenceHandle,
166166 #ifdef TEST_SESSION
182182 goto_if_error(r, "Error: FlushContext", error);
183183 #endif
184184
185 Esys_Free(result);
186 Esys_Free(validation);
187
185188 /* Check HMAC_Start with auth equal NULL */
186189
187190 #ifdef TEST_SESSION
246249 goto_if_error(r, "Error: FlushContext", error);
247250 #endif
248251
252 Esys_Free(outPublic);
253 Esys_Free(creationData);
254 Esys_Free(creationHash);
255 Esys_Free(creationTicket);
256 Esys_Free(result);
257 Esys_Free(validation);
249258 return EXIT_SUCCESS;
250259
251260 error:
264273 }
265274 #endif
266275
276 Esys_Free(outPublic);
277 Esys_Free(creationData);
278 Esys_Free(creationHash);
279 Esys_Free(creationTicket);
280 Esys_Free(result);
281 Esys_Free(validation);
267282 return EXIT_FAILURE;
268283 }
269284
5252 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
5353 ESYS_TR policySession = ESYS_TR_NONE;
5454
55 TPM2B_DIGEST *policyDigestTrial = NULL;
56 TPM2B_PUBLIC *outPublic = NULL;
57 TPM2B_CREATION_DATA *creationData = NULL;
58 TPM2B_DIGEST *creationHash = NULL;
59 TPMT_TK_CREATION *creationTicket = NULL;
60
61 TPM2B_PUBLIC *outPublic2 = NULL;
62 TPM2B_PRIVATE *outPrivate2 = NULL;
63 TPM2B_CREATION_DATA *creationData2 = NULL;
64 TPM2B_DIGEST *creationHash2 = NULL;
65 TPMT_TK_CREATION *creationTicket2 = NULL;
66
67 TPM2B_DATA *encryptionKeyOut = NULL;
68 TPM2B_PRIVATE *duplicate = NULL;
69 TPM2B_ENCRYPTED_SECRET *outSymSeed = NULL;
70
71 TPM2B_PUBLIC *keyPublic = NULL;
72 TPM2B_NAME *keyName = NULL;
73 TPM2B_NAME *keyQualifiedName = NULL;
74
75 TPM2B_NAME *nameKeySign = NULL;
76 TPM2B_PRIVATE *outPrivate = NULL;
77
5578 /*
5679 * Firth the policy value to be able to use Esys_Duplicate for an object has to be
5780 * determined with a policy trial session.
91114 );
92115 goto_if_error(r, "Error: PolicyCommandCode", error);
93116
94 TPM2B_DIGEST *policyDigestTrial;
95117 r = Esys_PolicyGetDigest(esys_context,
96118 sessionTrial,
97119 ESYS_TR_NONE,
172194 goto_if_error(r, "Error: TR_SetAuth", error);
173195
174196 RSRC_NODE_T *primaryHandle_node;
175 TPM2B_PUBLIC *outPublic;
176 TPM2B_CREATION_DATA *creationData;
177 TPM2B_DIGEST *creationHash;
178 TPMT_TK_CREATION *creationTicket;
179197
180198 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
181199 ESYS_TR_NONE, ESYS_TR_NONE,
184202 &outPublic, &creationData, &creationHash,
185203 &creationTicket);
186204 goto_if_error(r, "Error esys create primary", error);
205
206 Esys_Free(outPublic);
207 Esys_Free(creationData);
208 Esys_Free(creationHash);
209 Esys_Free(creationTicket);
187210
188211 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
189212 ESYS_TR_NONE, ESYS_TR_NONE,
268291 .count = 0,
269292 };
270293
271 TPM2B_PUBLIC *outPublic2;
272 TPM2B_PRIVATE *outPrivate2;
273 TPM2B_CREATION_DATA *creationData2;
274 TPM2B_DIGEST *creationHash2;
275 TPMT_TK_CREATION *creationTicket2;
276
277294 inPublic2.publicArea.authPolicy = *policyDigestTrial;
278295
279296 r = Esys_Create(esys_context,
302319 r = Esys_TR_SetAuth(esys_context, loadedKeyHandle, &authKey2);
303320 goto_if_error(r, "Error esys TR_SetAuth ", error);
304321
305 TPM2B_PUBLIC *keyPublic;
306 TPM2B_NAME *keyName;
307 TPM2B_NAME *keyQualifiedName;
308
309322 r = Esys_ReadPublic(esys_context,
310323 loadedKeyHandle,
311324 ESYS_TR_NONE,
315328 &keyName,
316329 &keyQualifiedName);
317330
331 Esys_Free(keyPublic);
332 Esys_Free(keyName);
333 Esys_Free(keyQualifiedName);
334
318335 goto_if_error(r, "Error esys ReadPublic", error);
319336
320337 TPMT_SYM_DEF policySymmetric = {.algorithm = TPM2_ALG_AES,
357374 TPMT_SYM_DEF_OBJECT symmetric = {.algorithm = TPM2_ALG_NULL,
358375 .keyBits = {.aes = 128},
359376 .mode = {.aes = TPM2_ALG_CFB}};
360
361 TPM2B_DATA *encryptionKeyOut;
362 TPM2B_PRIVATE *duplicate;
363 TPM2B_ENCRYPTED_SECRET *outSymSeed;
364377
365378 r = Esys_Duplicate(
366379 esys_context,
376389 &outSymSeed);
377390
378391 goto_if_error(r, "Error: Duplicate", error);
379
380 TPM2B_NAME *nameKeySign;
381 TPM2B_PRIVATE *outPrivate;
392 Esys_Free(outPublic);
382393
383394 r = Esys_ReadPublic(esys_context,
384395 loadedKeyHandle,
428439 r = Esys_FlushContext(esys_context, policySession);
429440 goto_if_error(r, "Flushing context", error);
430441
442 Esys_Free(policyDigestTrial);
443 Esys_Free(outPublic);
444 Esys_Free(creationData);
445 Esys_Free(creationHash);
446 Esys_Free(creationTicket);
447
448 Esys_Free(outPublic2);
449 Esys_Free(outPrivate2);
450 Esys_Free(creationData2);
451 Esys_Free(creationHash2);
452 Esys_Free(creationTicket2);
453
454 Esys_Free(encryptionKeyOut);
455 Esys_Free(duplicate);
456 Esys_Free(outSymSeed);
457
458 Esys_Free(keyQualifiedName);
459
460 Esys_Free(nameKeySign);
461 Esys_Free(outPrivate);
431462 return EXIT_SUCCESS;
432463
433464 error:
461492 }
462493 }
463494
495 Esys_Free(policyDigestTrial);
496 Esys_Free(outPublic);
497 Esys_Free(creationData);
498 Esys_Free(creationHash);
499 Esys_Free(creationTicket);
500
501 Esys_Free(outPublic2);
502 Esys_Free(outPrivate2);
503 Esys_Free(creationData2);
504 Esys_Free(creationHash2);
505 Esys_Free(creationTicket2);
506
507 Esys_Free(encryptionKeyOut);
508 Esys_Free(duplicate);
509 Esys_Free(outSymSeed);
510
511 Esys_Free(keyPublic);
512 Esys_Free(keyName);
513 Esys_Free(keyQualifiedName);
514
515 Esys_Free(nameKeySign);
516 Esys_Free(outPrivate);
464517 return EXIT_FAILURE;
465518 }
466519
5050 ESYS_TR primaryHandle = ESYS_TR_NONE;
5151 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
5252
53 TPM2B_PUBLIC *outPublic = NULL;
54 TPM2B_CREATION_DATA *creationData = NULL;
55 TPM2B_DIGEST *creationHash = NULL;
56 TPMT_TK_CREATION *creationTicket = NULL;
57
58 TPM2B_PUBLIC *outPublic2 = NULL;
59 TPM2B_PRIVATE *outPrivate2 = NULL;
60 TPM2B_CREATION_DATA *creationData2 = NULL;
61 TPM2B_DIGEST *creationHash2 = NULL;
62 TPMT_TK_CREATION *creationTicket2 = NULL;
63
64 TPM2B_PUBLIC *primaryKeyPublic = NULL;
65 TPM2B_NAME *primaryKeyName = NULL;
66 TPM2B_NAME *primaryKeyQualifiedName = NULL;
67
68 TPM2B_ID_OBJECT *credentialBlob = NULL;
69 TPM2B_ENCRYPTED_SECRET *secret = NULL;
70
71 TPM2B_DIGEST *certInfo = NULL;
72
5373 #ifdef TEST_SESSION
5474 ESYS_TR session = ESYS_TR_NONE;
5575 ESYS_TR session2 = ESYS_TR_NONE;
172192 goto_if_error(r, "Error: TR_SetAuth", error);
173193
174194 RSRC_NODE_T *primaryHandle_node;
175 TPM2B_PUBLIC *outPublic;
176 TPM2B_CREATION_DATA *creationData;
177 TPM2B_DIGEST *creationHash;
178 TPMT_TK_CREATION *creationTicket;
179195
180196 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
181197 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
261277 .count = 0,
262278 };
263279
264 TPM2B_PUBLIC *outPublic2;
265 TPM2B_PRIVATE *outPrivate2;
266 TPM2B_CREATION_DATA *creationData2;
267 TPM2B_DIGEST *creationHash2;
268 TPMT_TK_CREATION *creationTicket2;
269
270280 r = Esys_Create(esys_context,
271281 primaryHandle,
272282 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
291301 &loadedKeyHandle);
292302 goto_if_error(r, "Error esys load external", error);
293303
294 TPM2B_PUBLIC *primaryKeyPublic;
295 TPM2B_NAME *primaryKeyName;
296 TPM2B_NAME *primaryKeyQualifiedName;
297
298304 r = Esys_ReadPublic(esys_context,
299305 primaryHandle,
300306 ESYS_TR_NONE,
310316 .size = 20,
311317 .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
312318 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}};
313
314 TPM2B_ID_OBJECT *credentialBlob;
315 TPM2B_ENCRYPTED_SECRET *secret;
316319
317320 r = Esys_MakeCredential(esys_context,
318321 loadedKeyHandle,
329332 r = Esys_FlushContext(esys_context, loadedKeyHandle);
330333 goto_if_error(r, "Error esys flush context", error);
331334
332 TPM2B_DIGEST *certInfo;
333
334335 r = Esys_Load(esys_context,
335336 primaryHandle,
336337 #ifdef TEST_SESSION
382383 goto_if_error(r, "Flushing context", error);
383384 #endif
384385
386 Esys_Free(outPublic);
387 Esys_Free(creationData);
388 Esys_Free(creationHash);
389 Esys_Free(creationTicket);
390
391 Esys_Free(outPublic2);
392 Esys_Free(outPrivate2);
393 Esys_Free(creationData2);
394 Esys_Free(creationHash2);
395 Esys_Free(creationTicket2);
396
397 Esys_Free(primaryKeyPublic);
398 Esys_Free(primaryKeyName);
399 Esys_Free(primaryKeyQualifiedName);
400
401 Esys_Free(credentialBlob);
402 Esys_Free(secret);
403
404 Esys_Free(certInfo);
405
385406 return EXIT_SUCCESS;
386407
387408 error:
412433 }
413434 }
414435
436 Esys_Free(outPublic);
437 Esys_Free(creationData);
438 Esys_Free(creationHash);
439 Esys_Free(creationTicket);
440
441 Esys_Free(outPublic2);
442 Esys_Free(outPrivate2);
443 Esys_Free(creationData2);
444 Esys_Free(creationHash2);
445 Esys_Free(creationTicket2);
446
447 Esys_Free(primaryKeyPublic);
448 Esys_Free(primaryKeyName);
449 Esys_Free(primaryKeyQualifiedName);
450
451 Esys_Free(credentialBlob);
452 Esys_Free(secret);
453
454 Esys_Free(certInfo);
415455 return EXIT_FAILURE;
416456 }
417457
4343 ESYS_TR signHandle = ESYS_TR_NONE;
4444 ESYS_TR nvHandle = ESYS_TR_NONE;
4545 int failure_return = EXIT_FAILURE;
46
47 TPM2B_PUBLIC *outPublic = NULL;
48 TPM2B_CREATION_DATA *creationData = NULL;
49 TPM2B_DIGEST *creationHash = NULL;
50 TPMT_TK_CREATION *creationTicket = NULL;
51 TPM2B_ATTEST *certifyInfo = NULL;
52 TPMT_SIGNATURE *signature = NULL;
4653
4754 TPM2B_AUTH authValuePrimary = {
4855 .size = 5,
123130 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
124131 goto_if_error(r, "Error: TR_SetAuth", error);
125132
126 TPM2B_PUBLIC *outPublic;
127 TPM2B_CREATION_DATA *creationData;
128 TPM2B_DIGEST *creationHash;
129 TPMT_TK_CREATION *creationTicket;
130
131133 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
132134 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
133135 &inPublic, &outsideInfo, &creationPCR,
185187 offset);
186188 goto_if_error(r, "Error esys nv write", error);
187189
188 TPM2B_ATTEST *certifyInfo;
189 TPMT_SIGNATURE *signature;
190190 TPM2B_DATA qualifyingData = {0};
191191 TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL };
192192
227227 r = Esys_FlushContext(esys_context,signHandle);
228228 goto_if_error(r, "Error: FlushContext", error);
229229
230 Esys_Free(outPublic);
231 Esys_Free(creationData);
232 Esys_Free(creationHash);
233 Esys_Free(creationTicket);
234 Esys_Free(certifyInfo);
235 Esys_Free(signature);
230236 return EXIT_SUCCESS;
231237
232238 error:
248254 }
249255 }
250256
257 Esys_Free(outPublic);
258 Esys_Free(creationData);
259 Esys_Free(creationHash);
260 Esys_Free(creationTicket);
261 Esys_Free(certifyInfo);
262 Esys_Free(signature);
251263 return failure_return;
252264 }
253265
4040 {
4141 TSS2_RC r;
4242 ESYS_TR nvHandle = ESYS_TR_NONE;
43
44 TPM2B_NV_PUBLIC *nvPublic = NULL;
45 TPM2B_NAME *nvName = NULL;
46
47 TPM2B_MAX_NV_BUFFER *nv_test_data = NULL;
48
4349 #ifdef TEST_SESSION
4450 ESYS_TR session = ESYS_TR_NONE;
4551 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
103109
104110 goto_if_error(r, "Error esys define nv space", error);
105111
106 TPM2B_NV_PUBLIC *nvPublic;
107 TPM2B_NAME *nvName;
108
109112 r = Esys_NV_ReadPublic(esys_context,
110113 nvHandle,
111114 ESYS_TR_NONE,
138141
139142 goto_if_error(r, "Error esys nv write", error);
140143
144 Esys_Free(nvPublic);
145 Esys_Free(nvName);
146
141147 r = Esys_NV_ReadPublic(esys_context,
142148 nvHandle,
143149 ESYS_TR_NONE,
156162 goto error;
157163 }
158164
159 TPM2B_MAX_NV_BUFFER *nv_test_data;
165 Esys_Free(nvPublic);
166 Esys_Free(nvName);
160167
161168 r = Esys_NV_Read(esys_context,
162169 nvHandle,
210217 r = Esys_FlushContext(esys_context, session);
211218 goto_if_error(r, "Error: FlushContext", error);
212219 #endif
220
221 Esys_Free(nvPublic);
222 Esys_Free(nvName);
223 Esys_Free(nv_test_data);
213224 return EXIT_SUCCESS;
214225
215226 error:
237248 }
238249 #endif
239250
251 Esys_Free(nvPublic);
252 Esys_Free(nvName);
253 Esys_Free(nv_test_data);
240254 return EXIT_FAILURE;
241255 }
242256
4343
4444 TSS2_RC r;
4545 ESYS_TR nvHandle = ESYS_TR_NONE;
46
47 TPM2B_NV_PUBLIC *nvPublic = NULL;
48 TPM2B_NAME *nvName = NULL;
49 TPM2B_MAX_NV_BUFFER *nv_test_data2 = NULL;
50
4651 #ifdef TEST_SESSION
4752 ESYS_TR session = ESYS_TR_NONE;
4853 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
111116 .buffer={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
112117 1, 2, 3, 4, 5, 6, 7, 8, 9}};
113118
114 TPM2B_NV_PUBLIC *nvPublic;
115 TPM2B_NAME *nvName;
116
117119 r = Esys_NV_ReadPublic(
118120 esys_context,
119121 nvHandle,
148150 &nv_test_data);
149151
150152 goto_if_error(r, "Error esys nv write", error);
153 Esys_Free(nvPublic);
154 Esys_Free(nvName);
151155
152156 r = Esys_NV_ReadPublic(
153157 esys_context,
168172 goto error;
169173 }
170174
171 TPM2B_MAX_NV_BUFFER *nv_test_data2;
172
173175 r = Esys_NV_Read(
174176 esys_context,
175177 nvHandle,
186188 &nv_test_data2);
187189
188190 goto_if_error(r, "Error esys nv read", error);
191
192 Esys_Free(nvPublic);
193 Esys_Free(nvName);
189194
190195 r = Esys_NV_ReadPublic(
191196 esys_context,
224229 goto_if_error(r, "Flushing context", error);
225230 #endif
226231
232 Esys_Free(nvPublic);
233 Esys_Free(nvName);
234 Esys_Free(nv_test_data2);
227235 return EXIT_SUCCESS;
228236
229237 error:
251259 }
252260 #endif
253261
262 Esys_Free(nvPublic);
263 Esys_Free(nvName);
264 Esys_Free(nv_test_data2);
254265 return EXIT_FAILURE;
255266 }
256267
4848 {
4949 TSS2_RC r;
5050 ESYS_TR nvHandle = ESYS_TR_NONE;
51
52 TPM2B_NV_PUBLIC *nvPublic = NULL;
53 TPM2B_NAME *nvName = NULL;
54 TPM2B_MAX_NV_BUFFER *nv_test_data2 = NULL;
55
5156 #ifdef TEST_SESSION
5257 ESYS_TR session = ESYS_TR_NONE;
5358 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
117122 .buffer={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
118123 1, 2, 3, 4, 5, 6, 7, 8, 9}};
119124
120 TPM2B_NV_PUBLIC *nvPublic;
121 TPM2B_NAME *nvName;
122
123125 r = Esys_NV_ReadPublic(esys_context,
124126 nvHandle,
125127 ESYS_TR_NONE,
154156
155157 goto_if_error(r, "Error esys nv write", error);
156158
159 Esys_Free(nvPublic);
160 Esys_Free(nvName);
161
157162 r = Esys_NV_ReadPublic(esys_context,
158163 nvHandle,
159164 ESYS_TR_NONE,
171176 LOG_ERROR("Error: nv write name not equal");
172177 goto error;
173178 }
174
175 TPM2B_MAX_NV_BUFFER *nv_test_data2;
176179
177180 r = Esys_NV_Read(esys_context,
178181 nvHandle,
190193
191194 goto_if_error(r, "Error esys nv read", error);
192195
196 Esys_Free(nvPublic);
197 Esys_Free(nvName);
198 Esys_Free(nv_test_data2);
199
193200 r = Esys_NV_ReadPublic(esys_context,
194201 nvHandle,
195202 ESYS_TR_NONE,
221228 ESYS_TR_NONE
222229 );
223230 goto_if_error(r, "Error: NV_ReadLock", error);
231
232 Esys_Free(nvPublic);
233 Esys_Free(nvName);
224234
225235 r = Esys_NV_ReadPublic(esys_context,
226236 nvHandle,
269279 ESYS_TR_NONE
270280 );
271281 goto_if_error(r, "Error: NV_WriteLock", error);
282
283 Esys_Free(nvPublic);
284 Esys_Free(nvName);
272285
273286 r = Esys_NV_ReadPublic(esys_context,
274287 nvHandle,
320333 r = Esys_FlushContext(esys_context, session);
321334 goto_if_error(r, "Error: FlushContext", error);
322335 #endif
336
337 Esys_Free(nvPublic);
338 Esys_Free(nvName);
323339 return EXIT_SUCCESS;
324340
325341 error:
346362 }
347363 }
348364 #endif
365 Esys_Free(nvPublic);
366 Esys_Free(nvName);
367 Esys_Free(nv_test_data2);
349368 return EXIT_FAILURE;
350369 }
351370
4040 {
4141 TSS2_RC r;
4242 ESYS_TR nvHandle = ESYS_TR_NONE;
43
44 TPM2B_NV_PUBLIC *nvPublic = NULL;
45 TPM2B_NAME *nvName = NULL;
46 TPM2B_MAX_NV_BUFFER *nv_test_data = NULL;
47
4348 #ifdef TEST_SESSION
4449 ESYS_TR session = ESYS_TR_NONE;
4550 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
103108
104109 goto_if_error(r, "Error esys define nv space", error);
105110
106 TPM2B_NV_PUBLIC *nvPublic;
107 TPM2B_NAME *nvName;
108
109111 r = Esys_NV_ReadPublic(esys_context,
110112 nvHandle,
111113 ESYS_TR_NONE,
141143 bits);
142144
143145 goto_if_error(r, "Error esys nv write", error);
146 Esys_Free(nvPublic);
147 Esys_Free(nvName);
144148
145149 r = Esys_NV_ReadPublic(esys_context,
146150 nvHandle,
159163 LOG_ERROR("Error: nv write name not equal");
160164 goto error;
161165 }
162
163 TPM2B_MAX_NV_BUFFER *nv_test_data;
164166
165167 r = Esys_NV_Read(esys_context,
166168 nvHandle,
178180
179181 goto_if_error(r, "Error esys nv read", error);
180182
183 Esys_Free(nvPublic);
184 Esys_Free(nvName);
185
181186 r = Esys_NV_ReadPublic(esys_context,
182187 nvHandle,
183188 ESYS_TR_NONE,
214219 goto_if_error(r, "Error: FlushContext", error);
215220 #endif
216221
222 Esys_Free(nvPublic);
223 Esys_Free(nvName);
224 Esys_Free(nv_test_data);
217225 return EXIT_SUCCESS;
218226
219227 error:
241249 }
242250 #endif
243251
252 Esys_Free(nvPublic);
253 Esys_Free(nvName);
254 Esys_Free(nv_test_data);
244255 return EXIT_FAILURE;
245256 }
246257
4040 ESYS_TR primaryHandle = ESYS_TR_NONE;
4141 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
4242
43 TPM2B_PUBLIC *outPublic = NULL;
44 TPM2B_CREATION_DATA *creationData = NULL;
45 TPM2B_DIGEST *creationHash = NULL;
46 TPMT_TK_CREATION *creationTicket = NULL;
47
48 TPM2B_PUBLIC *outPublic2 = NULL;
49 TPM2B_PRIVATE *outPrivate2 = NULL;
50 TPM2B_CREATION_DATA *creationData2 = NULL;
51 TPM2B_DIGEST *creationHash2 = NULL;
52 TPMT_TK_CREATION *creationTicket2 = NULL;
53
54 TPM2B_PRIVATE *outPrivateChangeAuth = NULL;
55
4356 TPM2B_PUBLIC inPublic = {
4457 .size = 0,
4558 .publicArea = {
104117
105118 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
106119 goto_if_error(r, "Error: TR_SetAuth", error);
107
108 TPM2B_PUBLIC *outPublic;
109 TPM2B_CREATION_DATA *creationData;
110 TPM2B_DIGEST *creationHash;
111 TPMT_TK_CREATION *creationTicket;
112120
113121 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
114122 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
187195 .count = 0,
188196 };
189197
190 TPM2B_PUBLIC *outPublic2;
191 TPM2B_PRIVATE *outPrivate2;
192 TPM2B_CREATION_DATA *creationData2;
193 TPM2B_DIGEST *creationHash2;
194 TPMT_TK_CREATION *creationTicket2;
195
196198 r = Esys_Create(esys_context,
197199 primaryHandle,
198200 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
219221 .buffer={30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
220222 40, 41, 42, 43, 44, 45, 46, 47, 48, 49}};
221223
222 TPM2B_PRIVATE *outPrivateChangeAuth;
223
224224 r = Esys_ObjectChangeAuth(esys_context,
225225 loadedKeyHandle,
226226 primaryHandle,
238238 r = Esys_FlushContext(esys_context, primaryHandle);
239239 goto_if_error(r, "Error during FlushContext", error);
240240
241 SAFE_FREE(outPublic);
242 SAFE_FREE(creationData);
243 SAFE_FREE(creationHash);
244 SAFE_FREE(creationTicket);
245
246 SAFE_FREE(outPublic2);
247 SAFE_FREE(outPrivate2);
248 SAFE_FREE(creationData2);
249 SAFE_FREE(creationHash2);
250 SAFE_FREE(creationTicket2);
251
252 SAFE_FREE(outPrivateChangeAuth);
241253 return EXIT_SUCCESS;
242254
243255 error:
254266 }
255267 }
256268
269 SAFE_FREE(outPublic);
270 SAFE_FREE(creationData);
271 SAFE_FREE(creationHash);
272 SAFE_FREE(creationTicket);
273
274 SAFE_FREE(outPublic2);
275 SAFE_FREE(outPrivate2);
276 SAFE_FREE(creationData2);
277 SAFE_FREE(creationHash2);
278 SAFE_FREE(creationTicket2);
279
280 SAFE_FREE(outPrivateChangeAuth);
257281 return EXIT_FAILURE;
258282 }
259283
4141 int failure_return = EXIT_FAILURE;
4242
4343 TPMS_CAPABILITY_DATA *savedPCRs = NULL;
44 TPML_PCR_SELECTION *pcrSelectionOut = NULL;
45 TPML_DIGEST *pcrValues = NULL;
46 TPML_DIGEST_VALUES *digestsEvent = NULL;
4447
4548 ESYS_TR pcrHandle_handle = 16;
4649 TPML_DIGEST_VALUES digests
8083 }
8184 };
8285 UINT32 pcrUpdateCounter;
83 TPML_PCR_SELECTION *pcrSelectionOut;
84 TPML_DIGEST *pcrValues;
8586
8687 r = Esys_PCR_Read(
8788 esys_context,
106107 TPM2B_EVENT eventData = { .size = 20,
107108 .buffer={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
108109 1, 2, 3, 4, 5, 6, 7, 8, 9}};
109 TPML_DIGEST_VALUES *digestsEvent;
110
111110 r = Esys_PCR_Event(
112111 esys_context,
113112 pcrHandle_handle,
165164 goto_if_error(r, "Error: PCR_Allocate", error);
166165
167166 Esys_Free(savedPCRs);
168
167 Esys_Free(pcrSelectionOut);
168 Esys_Free(pcrValues);
169 Esys_Free(digestsEvent);
169170 return EXIT_SUCCESS;
170171
171172 error:
172 if (savedPCRs) Esys_Free(savedPCRs);
173 Esys_Free(savedPCRs);
174 Esys_Free(pcrSelectionOut);
175 Esys_Free(pcrValues);
176 Esys_Free(digestsEvent);
173177 return failure_return;
174178
175179 }
3939 ESYS_TR primaryHandle = ESYS_TR_NONE;
4040 ESYS_TR sessionTrial = ESYS_TR_NONE;
4141
42 TPM2B_PUBLIC *outPublic = NULL;
43 TPM2B_CREATION_DATA *creationData = NULL;
44 TPM2B_DIGEST *creationHash = NULL;
45 TPMT_TK_CREATION *creationTicket = NULL;
46
47 TPM2B_NAME *nameKeySign = NULL;
48 TPM2B_NAME *keyQualifiedName = NULL;
49 TPM2B_DIGEST *policyAuthorizeDigest = NULL;
50
4251 /*
4352 * 1. Create Primary. This primary will be used for PolicyAuthorize.
4453 */
111120 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
112121 goto_if_error(r, "Error: TR_SetAuth", error);
113122
114 TPM2B_PUBLIC *outPublic;
115 TPM2B_CREATION_DATA *creationData;
116 TPM2B_DIGEST *creationHash;
117 TPMT_TK_CREATION *creationTicket;
118
119123 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
120124 ESYS_TR_NONE, ESYS_TR_NONE,
121125 &inSensitivePrimary, &inPublic,
124128 &creationTicket);
125129 goto_if_error(r, "Error esys create primary", error);
126130
131 Esys_Free(outPublic);
132
127133 /*
128134 * 2. Create a trial policy with PolicyAuthorized. The name primary key
129135 * will be passed and the primary key will be used to sign policies.
144150 TPM2_SE_TRIAL, &symmetricTrial, TPM2_ALG_SHA1,
145151 &sessionTrial);
146152 goto_if_error(r, "Error: During initialization of policy trial session", error);
147
148 TPM2B_NAME *nameKeySign;
149 TPM2B_NAME *keyQualifiedName;
150153
151154 /* Dummy data for first call of PolicyAuthorize */
152155 TPM2B_DIGEST approvedPolicy = {0};
180183 );
181184 goto_if_error(r, "Error: PolicyAuthorize", error);
182185
183 TPM2B_DIGEST *policyAuthorizeDigest;
184186 r = Esys_PolicyGetDigest(esys_context,
185187 sessionTrial,
186188 ESYS_TR_NONE,
196198 r = Esys_FlushContext(esys_context, primaryHandle);
197199 goto_if_error(r, "Error: FlushContext", error);
198200
201 Esys_Free(outPublic);
202 Esys_Free(creationData);
203 Esys_Free(creationHash);
204 Esys_Free(creationTicket);
205
206 Esys_Free(nameKeySign);
207 Esys_Free(keyQualifiedName);
208 Esys_Free(policyAuthorizeDigest);
199209 return EXIT_SUCCESS;
200210
201211 error:
212222 }
213223 }
214224
225 Esys_Free(outPublic);
226 Esys_Free(creationData);
227 Esys_Free(creationHash);
228 Esys_Free(creationTicket);
229
230 Esys_Free(nameKeySign);
231 Esys_Free(keyQualifiedName);
232 Esys_Free(policyAuthorizeDigest);
215233 return EXIT_FAILURE;
216234 }
217235
4848 ESYS_TR nvHandle = ESYS_TR_NONE;
4949 ESYS_TR policySession = ESYS_TR_NONE;
5050
51 TPM2B_DIGEST *policyDigestTrial = NULL;
52
5153 /*
5254 * Firth the policy value for changing the auth value of an NV index has to be
5355 * determined with a policy trial session.
8789 );
8890 goto_if_error(r, "Error: PolicyCommandCode", error);
8991
90 TPM2B_DIGEST *policyDigestTrial;
9192 r = Esys_PolicyGetDigest(esys_context,
9293 sessionTrial,
9394 ESYS_TR_NONE,
122123 }
123124 };
124125
126
125127 r = Esys_NV_DefineSpace(esys_context,
126128 ESYS_TR_RH_OWNER,
127129 ESYS_TR_PASSWORD,
252254 r = Esys_FlushContext(esys_context, policySession);
253255 goto_if_error(r, "Flushing context", error);
254256
257 Esys_Free(policyDigestTrial);
255258 return EXIT_SUCCESS;
256259
257260 error:
279282 }
280283 }
281284
285 Esys_Free(policyDigestTrial);
282286 return EXIT_FAILURE;
283287 }
284288
4949 ESYS_TR policySession = ESYS_TR_NONE;
5050 ESYS_TR session = ESYS_TR_NONE;
5151 int failure_return = EXIT_FAILURE;
52
53 TPM2B_DIGEST *policyDigestTrial = NULL;
54
5255 /*
5356 * First the policy value for NV_UndefineSpaceSpecial has to be
5457 * determined with a policy trial session.
8891 );
8992 goto_if_error(r, "Error: PolicyCommandCode", error);
9093
91 TPM2B_DIGEST *policyDigestTrial;
9294 r = Esys_PolicyGetDigest(esys_context,
9395 sessionTrial,
9496 ESYS_TR_NONE,
131133 &publicInfo,
132134 &nvHandle);
133135
134 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH) {
136 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH ||
137 (r & ~TPM2_RC_N_MASK) == TPM2_RC_HIERARCHY) {
135138 /* Platform authorization not possible test will be skipped */
136139 LOG_WARNING("Platform authorization not possible.");
137140 failure_return = EXIT_SKIP;
214217 r = Esys_FlushContext(esys_context, policySession);
215218 goto_if_error(r, "Flushing context", error);
216219
220 Esys_Free(policyDigestTrial);
217221 return EXIT_SUCCESS;
218222
219223 error:
236240 }
237241 }
238242
243 Esys_Free(policyDigestTrial);
239244 return failure_return;
240245 }
241246
4646 ESYS_TR primaryHandle = ESYS_TR_NONE;
4747 ESYS_TR policySession = ESYS_TR_NONE;
4848
49 TPM2B_PUBLIC *outPublic = NULL;
50 TPM2B_CREATION_DATA *creationData = NULL;
51 TPM2B_DIGEST *creationHash = NULL;
52 TPMT_TK_CREATION *creationTicket = NULL;
53
54 TPM2B_DIGEST *policyDigestTrial = NULL;
55
56 TPM2B_PUBLIC *outPublic2 = NULL;
57 TPM2B_PRIVATE *outPrivate2 = NULL;
58 TPM2B_CREATION_DATA *creationData2 = NULL;
59 TPM2B_DIGEST *creationHash2 = NULL;
60 TPMT_TK_CREATION *creationTicket2 = NULL;
61
4962 /*
5063 * Firth the policy value for changing the auth value of an NV index has to be
5164 * determined with a policy trial session.
7891 );
7992 goto_if_error(r, "Error: PolicyPassword", error);
8093
81 TPM2B_DIGEST *policyDigestTrial;
8294 r = Esys_PolicyGetDigest(
8395 esys_context,
8496 sessionTrial,
157169 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
158170 goto_if_error(r, "Error: TR_SetAuth", error);
159171
160 TPM2B_PUBLIC *outPublic;
161 TPM2B_CREATION_DATA *creationData;
162 TPM2B_DIGEST *creationHash;
163 TPMT_TK_CREATION *creationTicket;
164
165172 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
166173 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
167174 &outsideInfo, &creationPCR, &primaryHandle,
259266 .count = 0,
260267 };
261268
262 TPM2B_PUBLIC *outPublic2;
263 TPM2B_PRIVATE *outPrivate2;
264 TPM2B_CREATION_DATA *creationData2;
265 TPM2B_DIGEST *creationHash2;
266 TPMT_TK_CREATION *creationTicket2;
267
268269 r = Esys_Create(esys_context,
269270 primaryHandle,
270271 policySession, ESYS_TR_NONE, ESYS_TR_NONE,
286287 r = Esys_FlushContext(esys_context, policySession);
287288 goto_if_error(r, "Flushing context", error);
288289
290 Esys_Free(outPublic);
291 Esys_Free(creationData);
292 Esys_Free(creationHash);
293 Esys_Free(creationTicket);
294
295 Esys_Free(policyDigestTrial);
296
297 Esys_Free(outPublic2);
298 Esys_Free(outPrivate2);
299 Esys_Free(creationData2);
300 Esys_Free(creationHash2);
301 Esys_Free(creationTicket2);
289302 return EXIT_SUCCESS;
290303
291304 error:
302315 }
303316 }
304317
318 Esys_Free(outPublic);
319 Esys_Free(creationData);
320 Esys_Free(creationHash);
321 Esys_Free(creationTicket);
322
323 Esys_Free(policyDigestTrial);
324
325 Esys_Free(outPublic2);
326 Esys_Free(outPrivate2);
327 Esys_Free(creationData2);
328 Esys_Free(creationHash2);
329 Esys_Free(creationTicket2);
305330 return EXIT_FAILURE;
306331 }
307332
4949 ESYS_TR session = ESYS_TR_NONE;
5050 ESYS_TR sessionTrial = ESYS_TR_NONE;
5151 int failure_return = EXIT_FAILURE;
52
5253 TPM2B_NONCE *nonceTPM = NULL;
54 TPM2B_PUBLIC *outPublic = NULL;
55 TPM2B_CREATION_DATA *creationData = NULL;
56 TPM2B_DIGEST *creationHash = NULL;
57 TPMT_TK_CREATION *creationTicket = NULL;
58 TPM2B_NAME *nameKeySign = NULL;
59 TPM2B_NAME *keyQualifiedName = NULL;
60 TPM2B_DIGEST *signed_digest = NULL;
61 TPM2B_TIMEOUT *timeout = NULL;
62 TPMT_TK_AUTH *policySignedTicket = NULL;
63 TPMT_TK_HASHCHECK *validation = NULL;
64 TPMT_TK_AUTH *policySecretTicket = NULL;
65 TPMT_SIGNATURE *signature = NULL;
5366
5467 /*
5568 * 1. Create Primary. This primary will be used as signing key.
123136 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
124137 goto_if_error(r, "Error: TR_SetAuth", error);
125138
126 TPM2B_PUBLIC *outPublic;
127 TPM2B_CREATION_DATA *creationData;
128 TPM2B_DIGEST *creationHash;
129 TPMT_TK_CREATION *creationTicket;
130
131139 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
132140 ESYS_TR_NONE, ESYS_TR_NONE,
133141 &inSensitivePrimary, &inPublic,
135143 &outPublic, &creationData, &creationHash,
136144 &creationTicket);
137145 goto_if_error(r, "Error esys create primary", error);
138
139 TPM2B_NAME *nameKeySign;
140 TPM2B_NAME *keyQualifiedName;
146 Esys_Free(outPublic);
147 Esys_Free(creationData);
148 Esys_Free(creationHash);
149 Esys_Free(creationTicket);
141150
142151 r = Esys_ReadPublic(esys_context,
143152 primaryHandle,
154163 * ticket policySignedTicket will be created.
155164 * With this ticket the function Esys_PolicyTicket will be tested.
156165 */
157 TPM2B_DIGEST *signed_digest;
158166 INT32 expiration = -(10*365*24*60*60); /* Expiration ten years */
159167
160168 TPM2B_DIGEST expiration2b;
184192
185193 TPM2B_NONCE policyRef = {0};
186194 TPM2B_DIGEST cpHashA = {0};
187 TPM2B_TIMEOUT *timeout;
188 TPMT_TK_AUTH *policySignedTicket;
189195
190196 r = Esys_TRSess_GetNonceTPM(esys_context, session, &nonceTPM);
191197 goto_if_error(r, "Error: During initialization of policy trial session", error);
217223 (const TPM2B_MAX_BUFFER *)nonceTPM
218224 );
219225 goto_if_error(r, "Error: SequenceUpdate", error);
220
221 TPMT_TK_HASHCHECK *validation;
222226
223227 r = Esys_SequenceComplete(esys_context,
224228 sequenceHandle_handle,
238242 .hierarchy = TPM2_RH_OWNER,
239243 .digest = {0}
240244 };
241 TPMT_SIGNATURE *signature;
242245
243246 /* Policy expiration of ten years will be signed */
244247
308311
309312 session = ESYS_TR_NONE;
310313 }
314 Esys_Free(timeout);
311315
312316 /*
313317 * 3. A policy tial session will be created. With this trial policy the
330334 TPM2_SE_TRIAL, &symmetricTrial, TPM2_ALG_SHA1,
331335 &sessionTrial);
332336 goto_if_error(r, "Error: During initialization of policy trial session", error);
333
334 TPMT_TK_AUTH *policySecretTicket;
335337
336338 r = Esys_PolicySecret(
337339 esys_context,
356358 r = Esys_FlushContext(esys_context, primaryHandle);
357359 goto_if_error(r, "Error: FlushContext", error);
358360
359 free(nonceTPM);
361 Esys_Free(outPublic);
362 Esys_Free(nameKeySign);
363 Esys_Free(keyQualifiedName);
364 Esys_Free(signed_digest);
365 Esys_Free(timeout);
366 Esys_Free(policySignedTicket);
367 Esys_Free(validation);
368 Esys_Free(policySecretTicket);
369 Esys_Free(nonceTPM);
370 Esys_Free(signature);
360371 return EXIT_SUCCESS;
361372
362373 error:
379390 }
380391 }
381392
382 if (nonceTPM)
383 free(nonceTPM);
393 Esys_Free(outPublic);
394 Esys_Free(creationData);
395 Esys_Free(creationHash);
396 Esys_Free(creationTicket);
397 Esys_Free(nameKeySign);
398 Esys_Free(keyQualifiedName);
399 Esys_Free(signed_digest);
400 Esys_Free(timeout);
401 Esys_Free(policySignedTicket);
402 Esys_Free(validation);
403 Esys_Free(policySecretTicket);
404 Esys_Free(nonceTPM);
405 Esys_Free(signature);
384406
385407 return failure_return;
386408 }
3737 {
3838 TSS2_RC r;
3939 ESYS_TR primaryHandle = ESYS_TR_NONE;
40
41 TPM2B_PUBLIC *outPublic = NULL;
42 TPM2B_CREATION_DATA *creationData = NULL;
43 TPM2B_DIGEST *creationHash = NULL;
44 TPMT_TK_CREATION *creationTicket = NULL;
45
46 TPM2B_ATTEST *attest = NULL;
47 TPMT_SIGNATURE *signature = NULL;
4048
4149 TPM2B_AUTH authValuePrimary = {
4250 .size = 5,
118126 goto_if_error(r, "Error: TR_SetAuth", error);
119127
120128 RSRC_NODE_T *primaryHandle_node;
121 TPM2B_PUBLIC *outPublic;
122 TPM2B_CREATION_DATA *creationData;
123 TPM2B_DIGEST *creationHash;
124 TPMT_TK_CREATION *creationTicket;
125129
126130 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
127131 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
157161 .pcrSelect = { 0,4,0 } },
158162 }};
159163
160 TPM2B_ATTEST *attest;
161 TPMT_SIGNATURE *signature;
162
163164 r = Esys_Quote(esys_context, primaryHandle,
164165 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
165166 &qualifyingData, &sig_scheme, &pcr_selection,
169170 r = Esys_FlushContext(esys_context, primaryHandle);
170171 goto_if_error(r, "Error: FlushContext", error);
171172
173 Esys_Free(outPublic);
174 Esys_Free(creationData);
175 Esys_Free(creationHash);
176 Esys_Free(creationTicket);
177
178 Esys_Free(attest);
179 Esys_Free(signature);
172180 return EXIT_SUCCESS;
173181
174182 error:
4040 TSS2_RC r;
4141 ESYS_TR primaryHandle = ESYS_TR_NONE;
4242
43 TPM2B_PUBLIC *outPublic = NULL;
44 TPM2B_CREATION_DATA *creationData = NULL;
45 TPM2B_DIGEST *creationHash = NULL;
46 TPMT_TK_CREATION *creationTicket = NULL;
47 TPM2B_PUBLIC_KEY_RSA *cipher = NULL;
48 TPM2B_PUBLIC_KEY_RSA *plain2 = NULL;
49 TPM2B_DATA * null_data = NULL;
50
4351 TPM2B_AUTH authValuePrimary = {
4452 .size = 5,
4553 .buffer = {1, 2, 3, 4, 5}
108116 goto_if_error(r, "Error: TR_SetAuth", error);
109117
110118 RSRC_NODE_T *primaryHandle_node;
111 TPM2B_PUBLIC *outPublic;
112 TPM2B_CREATION_DATA *creationData;
113 TPM2B_DIGEST *creationHash;
114 TPMT_TK_CREATION *creationTicket;
115119
116120 for (int mode = 0; mode <= 2; mode++) {
117121
134138 &primaryHandle, &outPublic, &creationData,
135139 &creationHash, &creationTicket);
136140 goto_if_error(r, "Error esys create primary", error);
141 Esys_Free(outPublic);
142 Esys_Free(creationData);
143 Esys_Free(creationHash);
144 Esys_Free(creationTicket);
137145
138146 r = esys_GetResourceObject(esys_context, primaryHandle,
139147 &primaryHandle_node);
150158 TPM2B_PUBLIC_KEY_RSA plain = {.size = plain_size,.buffer = {1, 2, 3}
151159 };
152160 TPMT_RSA_DECRYPT scheme;
153 TPM2B_DATA null_data = {.size = 0,.buffer = {}
154 };
155 TPM2B_PUBLIC_KEY_RSA *cipher;
156161
157162 if (mode == 0) {
158163 scheme.scheme = TPM2_ALG_NULL;
164169 }
165170 r = Esys_RSA_Encrypt(esys_context, primaryHandle, ESYS_TR_NONE,
166171 ESYS_TR_NONE, ESYS_TR_NONE, &plain, &scheme,
167 &null_data, &cipher);
172 null_data, &cipher);
168173 goto_if_error(r, "Error esys rsa encrypt", error);
169174
170 TPM2B_PUBLIC_KEY_RSA *plain2;
175 Esys_Free(null_data);
176
171177 r = Esys_RSA_Decrypt(esys_context, primaryHandle,
172178 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
173 cipher, &scheme, &null_data, &plain2);
179 cipher, &scheme, null_data, &plain2);
174180 goto_if_error(r, "Error esys rsa decrypt", error);
181
182 Esys_Free(null_data);
183 Esys_Free(cipher);
175184
176185 if (mode > 0 && memcmp(&plain.buffer[0], &plain2->buffer[0], plain_size)) {
177186 LOG_ERROR("plain texts are not equal for mode %i", mode);
180189
181190 r = Esys_FlushContext(esys_context, primaryHandle);
182191 goto_if_error(r, "Error: FlushContext", error);
192 Esys_Free(plain2);
183193 }
194
184195 return EXIT_SUCCESS;
185196
186197 error:
191202 }
192203 }
193204
205 Esys_Free(outPublic);
206 Esys_Free(creationData);
207 Esys_Free(creationHash);
208 Esys_Free(creationTicket);
209 Esys_Free(cipher);
210 Esys_Free(plain2);
211 Esys_Free(null_data);
194212 return EXIT_FAILURE;
195213 }
196214
4848 ESYS_TR loadedKeyHandle1 = ESYS_TR_NONE;
4949 ESYS_TR loadedKeyHandle2 = ESYS_TR_NONE;
5050
51 TPM2B_PUBLIC *outPublic = NULL;
52 TPM2B_CREATION_DATA *creationData = NULL;
53 TPM2B_DIGEST *creationHash = NULL;
54 TPMT_TK_CREATION *creationTicket = NULL;
55
56 TPM2B_PUBLIC *outPublic2 = NULL;
57 TPM2B_PRIVATE *outPrivate2 = NULL;
58 TPM2B_CREATION_DATA *creationData2 = NULL;
59 TPM2B_DIGEST *creationHash2 = NULL;
60 TPMT_TK_CREATION *creationTicket2 = NULL;
61
62 TPMS_CONTEXT *context = NULL;
63
5164 TPM2B_AUTH authValuePrimary = {
5265 .size = 5,
5366 .buffer = {1, 2, 3, 4, 5}
160173 goto_if_error(r, "Error: TR_SetAuth", error);
161174
162175 RSRC_NODE_T *primaryHandle_node;
163 TPM2B_PUBLIC *outPublic;
164 TPM2B_CREATION_DATA *creationData;
165 TPM2B_DIGEST *creationHash;
166 TPMT_TK_CREATION *creationTicket;
167176
168177 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
169178 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
263272 .count = 0,
264273 };
265274
266 TPM2B_PUBLIC *outPublic2;
267 TPM2B_PRIVATE *outPrivate2;
268 TPM2B_CREATION_DATA *creationData2;
269 TPM2B_DIGEST *creationHash2;
270 TPMT_TK_CREATION *creationTicket2;
271
272275 r = Esys_Create(esys_context,
273276 primaryHandle,
274277 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
290293 ESYS_TR_NONE, outPrivate2, outPublic2, &loadedKeyHandle1);
291294 goto_if_error(r, "Error esys load ", error);
292295
296 Esys_Free(outPublic2);
297 Esys_Free(outPrivate2);
298 Esys_Free(creationData2);
299 Esys_Free(creationHash2);
300 Esys_Free(creationTicket2);
301
293302 LOG_INFO("\nSecond Key loaded.");
294
295 TPMS_CONTEXT *context;
296303
297304 r = Esys_ContextSave(esys_context, loadedKeyHandle1, &context);
298305 goto_if_error(r, "Error esys context save", error);
328335 r = Esys_FlushContext(esys_context, loadedKeyHandle2);
329336 goto_if_error(r, "Error: FlushContext", error);
330337
338 Esys_Free(outPublic);
339 Esys_Free(creationData);
340 Esys_Free(creationHash);
341 Esys_Free(creationTicket);
342
343 Esys_Free(outPublic2);
344 Esys_Free(outPrivate2);
345 Esys_Free(creationData2);
346 Esys_Free(creationHash2);
347 Esys_Free(creationTicket2);
348
349 Esys_Free(context);
331350 return EXIT_SUCCESS;
332351
333352 error:
350369 }
351370 }
352371
372 Esys_Free(outPublic);
373 Esys_Free(creationData);
374 Esys_Free(creationHash);
375 Esys_Free(creationTicket);
376
377 Esys_Free(outPublic2);
378 Esys_Free(outPrivate2);
379 Esys_Free(creationData2);
380 Esys_Free(creationHash2);
381 Esys_Free(creationTicket2);
382
383 Esys_Free(context);
353384 return EXIT_FAILURE;
354385 }
355386
4242 TSS2_RC r;
4343 ESYS_TR objectHandle = ESYS_TR_NONE;
4444 ESYS_TR session = ESYS_TR_NONE;
45 TPM2B_DIGEST *rdata = NULL;
46
4547 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_XOR,
4648 .keyBits = { .exclusiveOr = TPM2_ALG_SHA1 },
4749 .mode = {.aes = TPM2_ALG_CFB}};
106108 .count = 0,
107109 };
108110
109 TPM2B_DIGEST *rdata;
110
111111 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
112112 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
113113 NULL,
158158
159159 r = Esys_GetRandom(esys_context, session, ESYS_TR_NONE, ESYS_TR_NONE,
160160 10, &rdata);
161 Esys_Free(rdata);
161162 transmit_hook = NULL;
162163 goto_if_error(r, "Error esapi create primary", error);
163164
174175 r = Esys_FlushContext(esys_context, session);
175176 goto_if_error(r, "Flushing context", error);
176177
178 Esys_Free(rdata);
177179 return EXIT_SUCCESS;
178180
179181 error:
191193 }
192194 }
193195
194
196 Esys_Free(rdata);
195197 return EXIT_FAILURE;
196198 }
197199
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright (c) 2020, Intel Corporation
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11
12 #include "tss2_esys.h"
13
14 #include "esys_iutil.h"
15 #include "test-esapi.h"
16 #define LOGDEFAULT LOGLEVEL_INFO
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** Test auth verification in clear command
22 *
23 * After TPM2_Clear command is executed all auth values for
24 * owner, platofrm and lockout are set to empty buffers and
25 * the empty auth values should be used fot HMAC verification
26 * in the response.
27 *
28 * @param[in,out] esys_context The ESYS_CONTEXT.
29 * @retval EXIT_SUCCESS
30 * @retval EXIT_SKIP
31 * @retval EXIT_FAILURE
32 */
33 int
34 test_esys_clear_auth(ESYS_CONTEXT * esys_context)
35 {
36 TSS2_RC r;
37 ESYS_TR session = ESYS_TR_NONE;
38 int failure_return = EXIT_FAILURE;
39
40 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_XOR,
41 .keyBits = { .exclusiveOr = TPM2_ALG_SHA1 },
42 .mode = {.aes = TPM2_ALG_CFB}};
43
44 /* Test lockout authorization */
45 LOG_DEBUG("Test LOCKOUT authorization");
46 LOG_DEBUG("Start Auth Session");
47 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
48 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
49 NULL,
50 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
51 &session);
52 goto_if_error(r, "Error: During initialization of session", error);
53
54 TPM2B_AUTH auth = {
55 .size = 16,
56 .buffer = "deadbeefdeadbeef",
57 };
58
59 LOG_DEBUG("Set Auth");
60 r = Esys_HierarchyChangeAuth(esys_context, ESYS_TR_RH_LOCKOUT,
61 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
62 &auth);
63
64 goto_if_error(r, "Error: During Esys_ObjectChangeAuth", error);
65 Esys_TR_SetAuth(esys_context, ESYS_TR_RH_LOCKOUT, &auth);
66
67 LOG_DEBUG("Clear");
68 r = Esys_Clear(esys_context, ESYS_TR_RH_LOCKOUT, session,
69 ESYS_TR_NONE, ESYS_TR_NONE);
70 goto_if_error(r, "Error: During Esys_Clear", error);
71
72 r = Esys_FlushContext(esys_context, session);
73 goto_if_error(r, "Error: During Esys_FlushContext", error);
74
75 /* Test platform authorization */
76 LOG_DEBUG("Test PLATFORM authorization");
77 LOG_DEBUG("Start Auth Session");
78 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
79 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
80 NULL,
81 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
82 &session);
83 goto_if_error(r, "Error: During initialization of session", error);
84
85 LOG_DEBUG("Set Auth");
86 r = Esys_HierarchyChangeAuth(esys_context, ESYS_TR_RH_PLATFORM,
87 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
88 &auth);
89
90 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_BAD_AUTH ||
91 (r & ~TPM2_RC_N_MASK) == TPM2_RC_HIERARCHY) {
92 /* Platform authorization not possible test will be skipped */
93 LOG_WARNING("Platform authorization not possible.");
94 failure_return = EXIT_SKIP;
95 goto error;
96 }
97 goto_if_error(r, "Error: During Esys_ObjectChangeAuth", error);
98
99 Esys_TR_SetAuth(esys_context, ESYS_TR_RH_PLATFORM, &auth);
100
101 LOG_DEBUG("Clear");
102 r = Esys_Clear(esys_context, ESYS_TR_RH_PLATFORM, session,
103 ESYS_TR_NONE, ESYS_TR_NONE);
104 goto_if_error(r, "Error: During Esys_Clear", error);
105
106 r = Esys_FlushContext(esys_context, session);
107 goto_if_error(r, "Error: During Esys_FlushContext", error);
108
109 Esys_TR_SetAuth(esys_context, ESYS_TR_RH_PLATFORM, &auth);
110
111 LOG_DEBUG("Set Auth");
112 r = Esys_HierarchyChangeAuth(esys_context, ESYS_TR_RH_PLATFORM,
113 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
114 NULL);
115
116 goto_if_error(r, "Error: During Esys_ObjectChangeAuth", error);
117
118 return EXIT_SUCCESS;
119
120 error:
121 LOG_ERROR("\nError Code: %x\n", r);
122
123 if (session != ESYS_TR_NONE) {
124 if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
125 LOG_ERROR("Cleanup session failed.");
126 }
127 }
128 return failure_return;
129 }
130
131 int
132 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
133 return test_esys_clear_auth(esys_context);
134 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4
5 #include <stdlib.h>
6
7 #include "tss2_esys.h"
8
9 #include "esys_iutil.h"
10 #define LOGMODULE test
11 #include "util/log.h"
12 #include "util/aux_util.h"
13
14 /** This tests the Esys_TR_ToTPMPublic function by
15 * creating a Primary Object Key and then attempting to retrieve
16 * the TPM2_HANDLE for it and validating that the handle is correct for the
17 * expected object type.
18 *
19 * Tested ESAPI commands:
20 * - Esys_CreatePrimary() (M)
21 * - Esys_EvictControl() (M)
22 * - Esys_FlushContext() (M)
23 * - Esys_TR_ToTPMPublic() (M)
24 *
25 * @param[in,out] ectx The ESYS_CONTEXT.
26 * @retval EXIT_FAILURE
27 * @retval EXIT_SUCCESS
28 */
29
30 int
31 test_esys_tr_toTpmPublic_key(ESYS_CONTEXT * ectx)
32 {
33 int rc = EXIT_FAILURE;
34
35 TSS2_RC r;
36 ESYS_TR primaryHandle = ESYS_TR_NONE;
37 ESYS_TR keyHandle = ESYS_TR_NONE;
38
39 TPM2B_AUTH authValuePrimary = {
40 .size = 5,
41 .buffer = {1, 2, 3, 4, 5}
42 };
43
44 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
45 .size = 0,
46 .sensitive = {
47 .userAuth = {
48 .size = 0,
49 .buffer = {0 },
50 },
51 .data = {
52 .size = 0,
53 .buffer = {0},
54 },
55 },
56 };
57
58 inSensitivePrimary.sensitive.userAuth = authValuePrimary;
59
60 TPM2B_PUBLIC inPublic = {
61 .size = 0,
62 .publicArea = {
63 .type = TPM2_ALG_RSA,
64 .nameAlg = TPM2_ALG_SHA256,
65 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
66 TPMA_OBJECT_RESTRICTED |
67 TPMA_OBJECT_DECRYPT |
68 TPMA_OBJECT_FIXEDTPM |
69 TPMA_OBJECT_FIXEDPARENT |
70 TPMA_OBJECT_SENSITIVEDATAORIGIN),
71 .authPolicy = {
72 .size = 0,
73 },
74 .parameters.rsaDetail = {
75 .symmetric = {
76 .algorithm = TPM2_ALG_AES,
77 .keyBits.aes = 128,
78 .mode.aes = TPM2_ALG_CFB},
79 .scheme = {
80 .scheme = TPM2_ALG_NULL
81 },
82 .keyBits = 2048,
83 .exponent = 0,
84 },
85 .unique.rsa = {
86 .size = 0,
87 .buffer = {},
88 },
89 },
90 };
91 LOG_INFO("\nRSA key will be created.");
92
93 TPM2B_DATA outsideInfo = {
94 .size = 0,
95 .buffer = {},
96 };
97
98 TPML_PCR_SELECTION creationPCR = {
99 .count = 0,
100 };
101
102 /* create a key */
103 r = Esys_CreatePrimary(ectx, ESYS_TR_RH_OWNER,
104 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
105 &inSensitivePrimary, &inPublic, &outsideInfo,
106 &creationPCR,
107 &primaryHandle, NULL, NULL, NULL, NULL);
108 goto_if_error(r, "Create primary", out);
109
110 /* the handle should be transient */
111 TPM2_HANDLE tpmHandle = ESYS_TR_NONE;
112 r = Esys_TR_GetTpmHandle(ectx, primaryHandle, &tpmHandle);
113 goto_if_error(r, "Esys_TR_ToTPMPublic", error);
114
115 if (!(tpmHandle & TPM2_HR_TRANSIENT)) {
116 LOG_ERROR("Retrieved handle should be transient, got: 0x%x", tpmHandle);
117 goto error;
118 }
119
120 /* make it persistent */
121 r = Esys_EvictControl(ectx, ESYS_TR_RH_OWNER, primaryHandle,
122 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
123 TPM2_PERSISTENT_FIRST, &keyHandle);
124 goto_if_error(r, "EvictControl make persistent", error);
125
126 /* handle should be persistent */
127 r = Esys_TR_GetTpmHandle(ectx, keyHandle, &tpmHandle);
128 goto_if_error(r, "Esys_TR_ToTPMPublic", error);
129
130 if (!(tpmHandle & TPM2_HR_PERSISTENT)) {
131 LOG_ERROR("Retrieved handle should be transient, got: 0x%x", tpmHandle);
132 goto error;
133 }
134
135 rc = EXIT_SUCCESS;
136
137 error:
138 r = Esys_FlushContext(ectx, primaryHandle);
139 if (r != TSS2_RC_SUCCESS) {
140 rc = EXIT_FAILURE;
141 LOG_ERROR("TR close on key object");
142 }
143
144 r = Esys_EvictControl(ectx, ESYS_TR_RH_OWNER, keyHandle,
145 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
146 TPM2_PERSISTENT_FIRST, &keyHandle);
147 if (r != TSS2_RC_SUCCESS) {
148 rc = EXIT_FAILURE;
149 LOG_ERROR("Esys_EvictControl");
150 }
151
152 out:
153 return rc;
154 }
155
156 int
157 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
158 return test_esys_tr_toTpmPublic_key(esys_context);
159 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <stdlib.h>
10
11 #include "tss2_esys.h"
12
13 #include "esys_iutil.h"
14 #define LOGMODULE test
15 #include "util/log.h"
16 #include "util/aux_util.h"
17
18 /** This tests the Esys_TR_ToTPMPublic function by
19 * creating an NV index object and then attempting to retrieve
20 * the TPM2_HANDLE for it and validating that the handle is correct for the
21 * expected object type.
22 *
23 * Tested ESAPI commands:
24 * - Esys_NV_DefineSpace() (M)
25 * - Esys_NV_UndefineSpace() (M)
26 * - Esys_TR_ToTPMPublic() (M)
27 *
28 * @param[in,out] ectx The ESYS_CONTEXT.
29 * @retval EXIT_FAILURE
30 * @retval EXIT_SUCCESS
31 */
32
33 int
34 test_esys_tr_toTpmPublic_nv(ESYS_CONTEXT * ectx)
35 {
36 int rc = EXIT_FAILURE;
37
38 TSS2_RC r;
39 ESYS_TR nvHandle = ESYS_TR_NONE;
40
41 TPM2B_AUTH auth = {.size = 20,
42 .buffer={10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
43 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}};
44
45 TPM2B_NV_PUBLIC publicInfo = {
46 .size = 0,
47 .nvPublic = {
48 .nvIndex =TPM2_NV_INDEX_FIRST,
49 .nameAlg = TPM2_ALG_SHA1,
50 .attributes = TPMA_NV_AUTHWRITE | TPMA_NV_AUTHREAD,
51 .authPolicy = {
52 .size = 0,
53 .buffer = {},
54 },
55 .dataSize = 1,
56 }
57 };
58
59 r = Esys_NV_DefineSpace(ectx, ESYS_TR_RH_OWNER,
60 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
61 &auth, &publicInfo, &nvHandle);
62 goto_if_error(r, "NV define space", out);
63
64 /* the handle should be NV */
65 TPM2_HANDLE tpmHandle = ESYS_TR_NONE;
66 r = Esys_TR_GetTpmHandle(ectx, nvHandle, &tpmHandle);
67 goto_if_error(r, "Esys_TR_ToTPMPublic", error);
68
69 if (!(tpmHandle & TPM2_HR_NV_INDEX)) {
70 LOG_ERROR("Retrieved handle should be NV, got: 0x%x", tpmHandle);
71 goto error;
72 }
73
74 rc = EXIT_SUCCESS;
75
76 error:
77 r = Esys_NV_UndefineSpace(ectx, ESYS_TR_RH_OWNER, nvHandle,
78 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE);
79 if (r != TSS2_RC_SUCCESS) {
80 LOG_ERROR("NV UndefineSpace");
81 rc = EXIT_FAILURE;
82 }
83 out:
84 return rc;
85 }
86
87 int
88 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
89 return test_esys_tr_toTpmPublic_nv(esys_context);
90 }
4646 int
4747 test_esys_unseal_password_auth(ESYS_CONTEXT * esys_context)
4848 {
49
5049 /*
5150 * 1. Create Primary
5251 */
5352 TSS2_RC r;
5453 ESYS_TR primaryHandle = ESYS_TR_NONE;
5554 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
55
56 TPM2B_PUBLIC *outPublic = NULL;
57 TPM2B_CREATION_DATA *creationData = NULL;
58 TPM2B_DIGEST *creationHash = NULL;
59 TPMT_TK_CREATION *creationTicket = NULL;
60 TPM2B_PUBLIC *outPublic2 = NULL;
61 TPM2B_PRIVATE *outPrivate2 = NULL;
62 TPM2B_CREATION_DATA *creationData2 = NULL;
63 TPM2B_DIGEST *creationHash2 = NULL;
64 TPMT_TK_CREATION *creationTicket2 = NULL;
65 TPM2B_SENSITIVE_DATA *outData = NULL;
5666
5767 TPM2B_AUTH authValuePrimary = {
5868 .size = 5,
125135 goto_if_error(r, "Error: TR_SetAuth", error);
126136
127137 RSRC_NODE_T *primaryHandle_node;
128 TPM2B_PUBLIC *outPublic;
129 TPM2B_CREATION_DATA *creationData;
130 TPM2B_DIGEST *creationHash;
131 TPMT_TK_CREATION *creationTicket;
132138
133139 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
134140 ESYS_TR_NONE, ESYS_TR_NONE,
237243 .count = 0,
238244 };
239245
240 TPM2B_PUBLIC *outPublic2;
241 TPM2B_PRIVATE *outPrivate2;
242 TPM2B_CREATION_DATA *creationData2;
243 TPM2B_DIGEST *creationHash2;
244 TPMT_TK_CREATION *creationTicket2;
245
246246 r = Esys_Create(esys_context,
247247 primaryHandle,
248248 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
278278 * 4. Unseal key
279279 */
280280
281 TPM2B_SENSITIVE_DATA *outData;
282
283281 r = Esys_Unseal(esys_context, loadedKeyHandle, ESYS_TR_PASSWORD,
284282 ESYS_TR_NONE, ESYS_TR_NONE, &outData);
285283 goto_if_error(r, "Error esys Unseal ", error);
304302 r = Esys_FlushContext(esys_context, loadedKeyHandle);
305303 goto_if_error(r, "Error during FlushContext", error);
306304
305 Esys_Free(outPublic);
306 Esys_Free(creationData);
307 Esys_Free(creationHash);
308 Esys_Free(creationTicket);
309 Esys_Free(outPublic2);
310 Esys_Free(outPrivate2);
311 Esys_Free(creationData2);
312 Esys_Free(creationHash2);
313 Esys_Free(creationTicket2);
314 Esys_Free(outData);
307315 return EXIT_SUCCESS;
308316
309317 error:
320328 }
321329 }
322330
331 Esys_Free(outPublic);
332 Esys_Free(creationData);
333 Esys_Free(creationHash);
334 Esys_Free(creationTicket);
335 Esys_Free(outPublic2);
336 Esys_Free(outPrivate2);
337 Esys_Free(creationData2);
338 Esys_Free(creationHash2);
339 Esys_Free(creationTicket2);
340 Esys_Free(outData);
323341 return EXIT_FAILURE;
324342 }
325343
3737 TSS2_RC r;
3838 ESYS_TR primaryHandle = ESYS_TR_NONE;
3939
40 TPM2B_PUBLIC *outPublic = NULL;
41 TPM2B_CREATION_DATA *creationData = NULL;
42 TPM2B_DIGEST *creationHash = NULL;
43 TPMT_TK_CREATION *creationTicket = NULL;
44
45 TPM2B_NAME *nameKeySign = NULL;
46 TPM2B_NAME *keyQualifiedName = NULL;
47 TPMT_SIGNATURE *signature = NULL;
48
49 TPMT_TK_VERIFIED *validation = NULL;
50
4051 /*
4152 * 1. Create Primary. This primary will be used as signing key.
4253 */
109120 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
110121 goto_if_error(r, "Error: TR_SetAuth", error);
111122
112 TPM2B_PUBLIC *outPublic;
113 TPM2B_CREATION_DATA *creationData;
114 TPM2B_DIGEST *creationHash;
115 TPMT_TK_CREATION *creationTicket;
116
117123 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
118124 ESYS_TR_NONE, ESYS_TR_NONE,
119125 &inSensitivePrimary, &inPublic,
121127 &outPublic, &creationData, &creationHash,
122128 &creationTicket);
123129 goto_if_error(r, "Error esys create primary", error);
124
125 TPM2B_NAME *nameKeySign;
126 TPM2B_NAME *keyQualifiedName;
130 Esys_Free(outPublic);
131 Esys_Free(creationData);
132 Esys_Free(creationHash);
133 Esys_Free(creationTicket);
127134
128135 r = Esys_ReadPublic(esys_context,
129136 primaryHandle,
142149 .hierarchy = TPM2_RH_OWNER,
143150 .digest = {0}
144151 };
145 TPMT_SIGNATURE *signature;
146152 /* SHA1 digest for PCR register with zeros */
147153 TPM2B_DIGEST pcr_digest_zero = {
148154 .size = 20,
166172 &signature);
167173 goto_if_error(r, "Error: Sign", error);
168174
169 TPMT_TK_VERIFIED *validation;
170
171175 r = Esys_VerifySignature(
172176 esys_context,
173177 primaryHandle,
182186 r = Esys_FlushContext(esys_context, primaryHandle);
183187 goto_if_error(r, "Error: FlushContext", error);
184188
189 Esys_Free(outPublic);
190
191 Esys_Free(nameKeySign);
192 Esys_Free(keyQualifiedName);
193 Esys_Free(signature);
194 Esys_Free(validation);
185195 return EXIT_SUCCESS;
186196
187197 error:
192202 }
193203 }
194204
205 Esys_Free(outPublic);
206 Esys_Free(creationData);
207 Esys_Free(creationHash);
208 Esys_Free(creationTicket);
209
210 Esys_Free(nameKeySign);
211 Esys_Free(keyQualifiedName);
212 Esys_Free(signature);
213 Esys_Free(validation);
195214 return EXIT_FAILURE;
196215 }
197216
5454 .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5555 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
5656 };
57
58 TPM2B_PUBLIC *outPublic = NULL;
59 TPM2B_CREATION_DATA *creationData = NULL;
60 TPM2B_DIGEST *creationHash = NULL;
61 TPMT_TK_CREATION *creationTicket = NULL;
62 TPM2B_ECC_POINT *outZ1 = NULL;
63 TPM2B_ECC_POINT *outZ2 = NULL;
64 TPM2B_ECC_POINT *Q = NULL;
5765
5866 memset(&sessionAttributes, 0, sizeof sessionAttributes);
5967
132140 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
133141 goto_if_error(r, "Error: TR_SetAuth", error);
134142
135 TPM2B_PUBLIC *outPublic;
136 TPM2B_CREATION_DATA *creationData;
137 TPM2B_DIGEST *creationHash;
138 TPMT_TK_CREATION *creationTicket;
139
140143 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, session,
141144 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic,
142145 &outsideInfo, &creationPCR, &eccHandle,
145148 goto_if_error(r, "Error esapi create primary", error);
146149
147150 TPMI_ECC_CURVE curveID = TPM2_ECC_NIST_P256;
148 TPM2B_ECC_POINT *Q;
149151 UINT16 counter;
150152
151153 r = Esys_EC_Ephemeral(
171173 .size = 0,
172174 .point = outPublic->publicArea.unique.ecc
173175 };
176 TPMI_ECC_KEY_EXCHANGE inScheme = TPM2_ALG_ECDH;
174177 TPM2B_ECC_POINT inQeB = *Q;
175 TPMI_ECC_KEY_EXCHANGE inScheme = TPM2_ALG_ECDH;
176 TPM2B_ECC_POINT *outZ1;
177 TPM2B_ECC_POINT *outZ2;
178178
179179 r = Esys_ZGen_2Phase(
180180 esys_context,
205205 r = Esys_FlushContext(esys_context, session);
206206 goto_if_error(r, "Flushing context", error);
207207
208 Esys_Free(outPublic);
209 Esys_Free(creationData);
210 Esys_Free(creationHash);
211 Esys_Free(creationTicket);
212 Esys_Free(outZ1);
213 Esys_Free(outZ2);
214 Esys_Free(Q);
208215 return EXIT_SUCCESS;
209216
210217 error:
222229 }
223230 }
224231
232 Esys_Free(outPublic);
233 Esys_Free(creationData);
234 Esys_Free(creationHash);
235 Esys_Free(creationTicket);
236 Esys_Free(outZ1);
237 Esys_Free(outZ2);
238 Esys_Free(Q);
225239 return failure_return;
226240 }
227241
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <unistd.h>
14
15 #include <openssl/evp.h>
16 #include <openssl/rsa.h>
17 #include <openssl/engine.h>
18 #include <openssl/pem.h>
19
20 #include "tss2_fapi.h"
21
22 #include "test-fapi.h"
23
24 #define LOGMODULE test
25 #include "util/log.h"
26 #include "util/aux_util.h"
27
28 #define SIZE 128
29
30 const char *priv_pem =
31 "-----BEGIN PRIVATE KEY-----\n"
32 "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCgYvoisJIDOeYg\n"
33 "jMF6ywiZbu085TLvy5ZMhq5vfYqdgefvwpemutnfKSnpYOs5B4yO/gAD7XiYluDv\n"
34 "tqlVhfISeQV04xrWGzNImenpwm/HsgueAu8VTHNtWSL96G+BLedGTrs2NqX6cxN7\n"
35 "yGl7dQpB5X8iP4XSvpjP3Vb7gs+adwCJR6xFkt60jYFmwrAdhEzOeakhimi5rU21\n"
36 "LxCkRdEyaxS57X15L9dEA+aYJ+dvkFfZOfTqIKmTrA75F8yj161xflwtIC4hgRBg\n"
37 "K9Xb/RdN8TDrTu+20E3RjngutU4qejW9Fd3mzHJGV8HRYvjYXhUblN9wmjm7Veru\n"
38 "T2b0rnvzAgMBAAECggEBAIwHvoJ5DRJ6A50Zp3dROxHTEphfOEi6xF/OGxBGWLbK\n"
39 "C7l+eS9d5gj8BJa5QsXI/IR/6X2EYQ1AdeV04oVD7CUKuqPiALU8jFrv3pV0aGm+\n"
40 "3nu37gv3crPe5jkvLeNoM4tkA/oCXom63SDuyoG6nxkHiSdatLlaJUse4em3vRAL\n"
41 "QivziZIMyswcleMe0xAoMi7LO+nUFFxBS8/xGya0vsU0dsMQEl1SRITv1VCXmPQD\n"
42 "T4dEI4+1cufv6Ax0EDbFKmnjyiGTjOeQKrGIqETUSQolbg5PgL1XZehaaxM822OY\n"
43 "Qpnp5T0XhUEmVrOb2Wrboj+dC/2tgAN/fWXjAAxnm2ECgYEA02UTZuZ+QnD6tqo3\n"
44 "/y3n5kaM9uA2mdOIqgECI9psGF1IBIC/iP2diKyuvmQL8hzymComb5YzZl3TOAga\n"
45 "WHQYbIeU3JhnYTG75/Dv5Zh32H4NjkIJHT2/8LUM25Ove9u6QAniVgIQpBZ47LjX\n"
46 "9jHjTYCW5n79qNSfu0egYJUvypECgYEAwjqWzzEINqnX/xIVCoB4XpuDuSdkM0JW\n"
47 "MZDIH9xHjZPp07/5XYEoITylk6Zwbh+djvWDNP4gzPtuK26VsqrNxoWMsFZeXn6U\n"
48 "xSOYL2UNCZiOgchdZCOr+6r8LRUuo8xHjbawVoJVK1+tZ2WsR3ilt3Gw34O8Z5ep\n"
49 "f4v7GOXw+EMCgYAUHjFrgJIRhqkFi0uK+HZyXtJ5iDsKBqyh6Tin6tiQtQfujcYs\n"
50 "pl5ArJZwvhq47vJTcud3hSbdHh7E3ViMhHfylDChkct833vPhgl+ozT8oHpvyG8P\n"
51 "nlnO8ZwIpZR0yCOAhrBImSe2RgE6HhlHb9X/ATbbNsizMZEGBLoJlwkWUQKBgQCy\n"
52 "4U7fh2LvJUF+82JZh7RUPZn1Pmg0JVZI0/TcEv37UEy77kR1b2xMIBTGhTVq1sc/\n"
53 "ULIEbkA7SR1P9sr7//8AZSMLjJ/hG2dcoMmabNCzE8O7l5MblRbh87nIs4d+57bG\n"
54 "t4h0RBi4l6eWYLdoI59L8fNaB3PPXIiIpZ0eczeZDQKBgQC2vuFYpUZqDb9CaJsn\n"
55 "Luee6P6n5v3ZBTAT4E+GG1kWS28BiebcCuLKNAY4ZtLo08ozaTWcMxooOTeka2ux\n"
56 "fQDE4M/LTNpam8QOJ2hqECF5a0uBYNcbmaGtfA9KwIgwCZZYuwb5IDq/DRPuR690\n"
57 "i8Kp6jR2wY0suObmZHKvbCB1Dw==\n"
58 "-----END PRIVATE KEY-----\n";
59
60 const char *pub_pem =
61 "-----BEGIN PUBLIC KEY-----\n"
62 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoGL6IrCSAznmIIzBessI\n"
63 "mW7tPOUy78uWTIaub32KnYHn78KXprrZ3ykp6WDrOQeMjv4AA+14mJbg77apVYXy\n"
64 "EnkFdOMa1hszSJnp6cJvx7ILngLvFUxzbVki/ehvgS3nRk67Njal+nMTe8hpe3UK\n"
65 "QeV/Ij+F0r6Yz91W+4LPmncAiUesRZLetI2BZsKwHYRMznmpIYpoua1NtS8QpEXR\n"
66 "MmsUue19eS/XRAPmmCfnb5BX2Tn06iCpk6wO+RfMo9etcX5cLSAuIYEQYCvV2/0X\n"
67 "TfEw607vttBN0Y54LrVOKno1vRXd5sxyRlfB0WL42F4VG5TfcJo5u1Xq7k9m9K57\n"
68 "8wIDAQAB\n"
69 "-----END PUBLIC KEY-----\n";
70
71 #define RSA_SIG_SCHEME RSA_PKCS1_PSS_PADDING
72
73 char *userDataTest = "test";
74
75 #define chknull(X) if (!X) { LOG_ERROR(str(X) "should not be null"); \
76 r = TSS2_FAPI_RC_GENERAL_FAILURE; \
77 goto error_cleanup; }
78
79 static TSS2_RC
80 signatureCallback(
81 FAPI_CONTEXT *context,
82 char const *description,
83 char const *publicKey,
84 char const *publicKeyHint,
85 uint32_t hashAlg,
86 uint8_t const *dataToSign,
87 size_t dataToSignSize,
88 uint8_t **signature,
89 size_t *signatureSize,
90 void *userData)
91 {
92 (void)description;
93 (void)publicKey;
94 (void)publicKeyHint;
95
96 if (userData != userDataTest) {
97 LOG_ERROR("userData is not correct, %p != %p", userData, userDataTest);
98 return TSS2_FAPI_RC_GENERAL_FAILURE;
99 }
100
101 if (hashAlg != TPM2_ALG_SHA1) {
102 LOG_ERROR("hashAlg is not correct, %u != %u", hashAlg, TPM2_ALG_SHA1);
103 return TSS2_FAPI_RC_GENERAL_FAILURE;
104 }
105
106 TSS2_RC r = TSS2_RC_SUCCESS;
107 EVP_PKEY *priv_key = NULL;
108 BIO *bufio = NULL;
109 EVP_MD_CTX *mdctx =NULL;
110 EVP_PKEY_CTX *pctx = NULL;
111
112 const EVP_MD *ossl_hash = EVP_sha1();
113 chknull(ossl_hash);
114
115 LOGBLOB_DEBUG(dataToSign, dataToSignSize, "Data to be signed");
116
117 bufio = BIO_new_mem_buf((void *)priv_pem, strlen(priv_pem));
118 priv_key = PEM_read_bio_PrivateKey(bufio, NULL, NULL, NULL);
119 chknull(priv_key);
120
121 mdctx = EVP_MD_CTX_create();
122 chknull(mdctx);
123
124 if (1 != EVP_DigestSignInit(mdctx, &pctx, NULL, NULL, priv_key)) {
125 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL digest sign init.",
126 error_cleanup);
127 }
128 if (EVP_PKEY_type(EVP_PKEY_id(priv_key)) == EVP_PKEY_RSA) {
129 int signing_scheme = RSA_SIG_SCHEME;
130 if (1 != EVP_PKEY_CTX_set_rsa_padding(pctx, signing_scheme)) {
131 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL set RSA padding.",
132 error_cleanup);
133 }
134 }
135 if (1 != EVP_DigestSignInit(mdctx, &pctx, ossl_hash, NULL, priv_key)) {
136 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign init.",
137 error_cleanup);
138 }
139 if (1 != EVP_DigestSignUpdate(mdctx, dataToSign, dataToSignSize)) {
140 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign update.",
141 error_cleanup);
142 }
143 if (1 != EVP_DigestSignFinal(mdctx, NULL, signatureSize)) {
144 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign final.",
145 error_cleanup);
146 }
147 *signature = malloc(*signatureSize);
148 chknull(*signature);
149 if (1 != EVP_DigestSignFinal(mdctx, *signature, signatureSize)) {
150 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign final.",
151 error_cleanup);
152 }
153 error_cleanup:
154 if (priv_key)
155 EVP_PKEY_free(priv_key);
156 if (mdctx)
157 EVP_MD_CTX_destroy(mdctx);
158 if (bufio)
159 BIO_free(bufio);
160 return r;
161 }
162
163 /** Test the FAPI functions for encryption and decryption.
164 *
165 * Tested FAPI commands:
166 * - Fapi_Provision()
167 * - Fapi_Import()
168 * - Fapi_CreateKey()
169 * - Fapi_SetSignCB()
170 * - Fapi_Encrypt()
171 * - Fapi_Decrypt()
172 * - Fapi_Free()
173 *
174 * Tested Policies:
175 * - PolicySigned
176 *
177 * @param[in,out] context The FAPI_CONTEXT.
178 * @retval EXIT_FAILURE
179 * @retval EXIT_SUCCESS
180 */
181 int
182 test_fapi_data_crypt(FAPI_CONTEXT *context)
183 {
184
185 TSS2_RC r;
186 long policy_size;
187 const char *policy_name = "/policy/pol_signed";
188 const char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_signed.json";
189 FILE *stream = NULL;
190 char *json_policy = NULL;
191
192 uint8_t *cipherText = NULL;
193 size_t cipherTextSize;
194
195 r = Fapi_Provision(context, NULL, NULL, NULL);
196 goto_if_error(r, "Error Fapi_Provision", error);
197
198 r = pcr_reset(context, 16);
199 goto_if_error(r, "Error pcr_reset", error);
200
201 stream = fopen(policy_file, "r");
202 if (!stream) {
203 LOG_ERROR("File %s does not exist", policy_file);
204 goto error;
205 }
206 fseek(stream, 0L, SEEK_END);
207 policy_size = ftell(stream);
208 fclose(stream);
209 json_policy = malloc(policy_size + 1);
210 goto_if_null(json_policy,
211 "Could not allocate memory for the JSON policy",
212 TSS2_FAPI_RC_MEMORY, error);
213 stream = fopen(policy_file, "r");
214 ssize_t ret = read(fileno(stream), json_policy, policy_size);
215 if (ret != policy_size) {
216 LOG_ERROR("IO error %s.", policy_file);
217 goto error;
218 }
219 json_policy[policy_size] = '\0';
220
221 r = Fapi_Import(context, policy_name, json_policy);
222 goto_if_error(r, "Error Fapi_Import", error);
223
224 r = Fapi_CreateKey(context, "HS/SRK/myRsaCryptKey", "decrypt",
225 policy_name, NULL);
226 goto_if_error(r, "Error Fapi_CreateKey", error);
227
228 uint8_t plainText[SIZE];
229 int i;
230
231 for (i = 0; i < SIZE; i++)
232 plainText[i] = i % 256;
233
234 r = Fapi_SetSignCB(context, signatureCallback, userDataTest);
235 goto_if_error(r, "Error SetPolicySignatureCallback", error);
236
237 r = Fapi_Encrypt(context, "HS/SRK/myRsaCryptKey", &plainText[0],
238 SIZE, &cipherText, &cipherTextSize);
239
240 if (r == TSS2_FAPI_RC_NOT_IMPLEMENTED) {
241 goto skip;
242 }
243
244 goto_if_error(r, "Error Fapi_Encrypt", error);
245
246 uint8_t *plainText2 = NULL;
247 size_t plainText2_size = 0;
248
249 r = Fapi_Decrypt(context, "HS/SRK/myRsaCryptKey", cipherText, cipherTextSize,
250 &plainText2, &plainText2_size);
251 goto_if_error(r, "Error Fapi_Encrypt", error);
252
253 if (plainText2_size != SIZE ||
254 memcmp(plainText, plainText2, plainText2_size) != 0) {
255 LOG_ERROR("Error: decrypted text not equal to origin");
256 goto error;
257 }
258
259 Fapi_Free(cipherText);
260 Fapi_Free(plainText2);
261 Fapi_Free(json_policy);
262 Fapi_Delete(context, "/");
263
264 return EXIT_SUCCESS;
265
266 error:
267 Fapi_Free(cipherText);
268 Fapi_Free(json_policy);
269 Fapi_Delete(context, "/");
270
271 return EXIT_FAILURE;
272
273 skip:
274 Fapi_Free(json_policy);
275 Fapi_Delete(context, "/");
276
277 return EXIT_SKIP;
278 }
279
280 int
281 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
282 {
283 return test_fapi_data_crypt(fapi_context);
284 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <unistd.h>
13
14 #include "tss2_fapi.h"
15
16 #include "test-fapi.h"
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 #define SIZE 2000
22
23 /** Test the FAPI functions for key duplication.
24 *
25 * Tested FAPI commands:
26 * - Fapi_Provision()
27 * - Fapi_Import()
28 * - Fapi_CreateKey()
29 * - Fapi_ExportKey()
30 * - Fapi_Delete()
31 *
32 * Tested Policies:
33 * - PolicyDuplicationSelect
34 *
35 * @param[in,out] context The FAPI_CONTEXT.
36 * @retval EXIT_FAILURE
37 * @retval EXIT_SUCCESS
38 */
39 int
40 test_fapi_duplicate(FAPI_CONTEXT *context)
41 {
42 TSS2_RC r;
43 char *policy_name = "/policy/pol_duplicate";
44 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_duplicate.json";
45 FILE *stream = NULL;
46 char *json_policy = NULL;
47 long policy_size;
48 char *json_duplicate = NULL;
49 char *json_string_pub_key = NULL;
50
51 r = Fapi_Provision(context, NULL, NULL, NULL);
52 goto_if_error(r, "Error Fapi_Provision", error);
53
54 r = pcr_reset(context, 16);
55 goto_if_error(r, "Error pcr_reset", error);
56
57 stream = fopen(policy_file, "r");
58 if (!stream) {
59 LOG_ERROR("File %s does not exist", policy_file);
60 goto error;
61 }
62 fseek(stream, 0L, SEEK_END);
63 policy_size = ftell(stream);
64 fclose(stream);
65 json_policy = malloc(policy_size + 1);
66 goto_if_null(json_policy,
67 "Could not allocate memory for the JSON policy",
68 TSS2_FAPI_RC_MEMORY, error);
69 stream = fopen(policy_file, "r");
70 ssize_t ret = read(fileno(stream), json_policy, policy_size);
71 if (ret != policy_size) {
72 LOG_ERROR("IO error %s.", policy_file);
73 goto error;
74 }
75 json_policy[policy_size] = '\0';
76
77 r = Fapi_Import(context, policy_name, json_policy);
78 goto_if_error(r, "Error Fapi_List", error);
79
80 r = Fapi_CreateKey(context, "HS/SRK/myCryptKey", "restricted,decrypt,noDa",
81 "", NULL);
82 goto_if_error(r, "Error Fapi_CreateKey", error);
83
84 r = Fapi_ExportKey(context, "HS/SRK/myCryptKey", NULL, &json_string_pub_key);
85 goto_if_error(r, "Error Fapi_CreateKey", error);
86
87 r = Fapi_Import(context, "ext/myNewParent", json_string_pub_key);
88 goto_if_error(r, "Error Fapi_Import", error);
89
90 r = Fapi_CreateKey(context, "HS/SRK/myCryptKey/myCryptKey2",
91 "exportable,decrypt,noDa", policy_name, NULL);
92 goto_if_error(r, "Error Fapi_CreateKey", error);
93
94 r = Fapi_ExportKey(context, "HS/SRK/myCryptKey/myCryptKey2",
95 "ext/myNewParent", &json_duplicate);
96 goto_if_error(r, "Error Fapi_CreateKey", error);
97
98 fprintf(stderr, "\nExport Data:\n%s\n", json_duplicate);
99
100 r = Fapi_Import(context, "importedKey", json_duplicate);
101 goto_if_error(r, "Error Fapi_Import", error);
102
103 fprintf(stderr, "Duplicate:\n%s\n", json_duplicate);
104
105 r = Fapi_Delete(context, "/");
106 goto_if_error(r, "Error Fapi_Delete", error);
107
108 SAFE_FREE(json_string_pub_key);
109 SAFE_FREE(json_duplicate);
110 SAFE_FREE(json_policy);
111 return EXIT_SUCCESS;
112
113 error:
114 SAFE_FREE(json_string_pub_key);
115 SAFE_FREE(json_duplicate);
116 SAFE_FREE(json_policy);
117 return EXIT_FAILURE;
118 }
119
120 int
121 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
122 {
123 return test_fapi_duplicate(fapi_context);
124 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <openssl/evp.h>
11 #include <openssl/aes.h>
12 #include <openssl/rsa.h>
13 #include <openssl/engine.h>
14 #include <openssl/pem.h>
15 #include <stdio.h>
16 #include <stddef.h>
17 #include <string.h>
18 #include <inttypes.h>
19
20 #include "tss2_fapi.h"
21
22 #define LOGMODULE test
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 /** Test the FAPI functions use an external public key for signature and quote verify without TPM.
27 *
28 * Tested FAPI commands:
29 * - Fapi_Import()
30 * - Fapi_VerifySignature()
31 * - Fapi_SetCertificate()
32 * - Fapi_GetCertificate()
33 * - Fapi_List()
34 * - Fapi_VerifyQuote()
35 * - Fapi_Delete()
36 *
37 * @param[in,out] context The FAPI_CONTEXT.
38 * @retval EXIT_FAILURE
39 * @retval EXIT_SUCCESS
40 */
41 int
42 test_fapi_ext_public_key(FAPI_CONTEXT *context)
43 {
44
45 TSS2_RC r;
46 BIO *bufio = NULL;
47
48 EVP_PKEY *evp_key = NULL;
49 RSA *rsa_key = NULL;
50
51 /* Key will be used for non TPM signature verfication. */
52 char *pubkey_pem =
53 "-----BEGIN PUBLIC KEY-----\n"
54 "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUymzBzI3LcxRpqJkiP0Ks7qp1UZH\n"
55 "93mYpmfUJBjK6anQawTyy8k87MteUdP5IPy47gzsO7sFcbWCoVZ8LvoQUw==\n"
56 "-----END PUBLIC KEY-----\n";
57
58 /* Quote info will be used for non TPM signature verfication. */
59 const char *quote_info =
60 "{\n"
61 " \"sig_scheme\":{\n"
62 " \"scheme\":\"ECDSA\",\n"
63 " \"details\":{\n"
64 " \"hashAlg\":\"SHA256\"\n"
65 " }\n"
66 " },\n"
67 " \"attest\":{\n"
68 " \"magic\":\"VALUE\",\n"
69 " \"type\":\"ATTEST_QUOTE\",\n"
70 " \"qualifiedSigner\":\"000b6f2f5ee244f7af20dbdfdf0a7dd21ef28afd9c3f377758f9ace6e29e64fc0ccf\",\n"
71 " \"extraData\":\"6768033e216468247bd031a0a2d9876d79818f8f\",\n"
72 " \"clockInfo\":{\n"
73 " \"clock\":4607,\n"
74 " \"resetCount\":2327013047,\n"
75 " \"restartCount\":1164757112,\n"
76 " \"safe\":\"YES\"\n"
77 " },\n"
78 " \"firmwareVersion\":[\n"
79 " 635916457,\n"
80 " 1185938286\n"
81 " ],\n"
82 " \"attested\":{\n"
83 " \"pcrSelect\":[\n"
84 " {\n"
85 " \"hash\":\"SHA256\",\n"
86 " \"pcrSelect\":[\n"
87 " 16\n"
88 " ]\n"
89 " }\n"
90 " ],\n"
91 " \"pcrDigest\":\"224eb2f4e5625ecb4a31cb7df43282ef6293c97a840a33415a3afe069535fa9b\"\n"
92 " }\n"
93 " }\n"
94 "}\n";
95
96 /* Test signature will be used for non TPM signature verfication. */
97 size_t test_signature_size = 71;
98 const uint8_t test_signature[71] = {
99 0x30, 0x45, 0x02, 0x21, 0x00, 0x8a, 0x00, 0x01,
100 0x6b, 0x79, 0xe2, 0x50, 0x84, 0x52, 0xc3, 0x40,
101 0xbb, 0x6c, 0xb4, 0xcb, 0x31, 0x42, 0xa2, 0xe5,
102 0x8b, 0x36, 0x35, 0x46, 0x8d, 0x8c, 0x3e, 0x59,
103 0xda, 0x0e, 0x83, 0x7e, 0x3b, 0x02, 0x20, 0x77,
104 0xb1, 0xe6, 0xa8, 0xab, 0x0e, 0x5f, 0x72, 0x28,
105 0x3e, 0x35, 0xe5, 0x91, 0x5b, 0x13, 0x35, 0xfe,
106 0x44, 0x54, 0xa4, 0x79, 0x63, 0x2a, 0x94, 0xd5,
107 0xaa, 0x07, 0xce, 0xba, 0xc6, 0x56, 0x85
108 };
109
110 /* Qualifying data will be used for non TPM signature verfication. */
111 uint8_t qualifying_data[20] = {
112 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
113 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
114 };
115
116 const char *pub_pem =
117 "-----BEGIN PUBLIC KEY-----\n"
118 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoGL6IrCSAznmIIzBessI\n"
119 "mW7tPOUy78uWTIaub32KnYHn78KXprrZ3ykp6WDrOQeMjv4AA+14mJbg77apVYXy\n"
120 "EnkFdOMa1hszSJnp6cJvx7ILngLvFUxzbVki/ehvgS3nRk67Njal+nMTe8hpe3UK\n"
121 "QeV/Ij+F0r6Yz91W+4LPmncAiUesRZLetI2BZsKwHYRMznmpIYpoua1NtS8QpEXR\n"
122 "MmsUue19eS/XRAPmmCfnb5BX2Tn06iCpk6wO+RfMo9etcX5cLSAuIYEQYCvV2/0X\n"
123 "TfEw607vttBN0Y54LrVOKno1vRXd5sxyRlfB0WL42F4VG5TfcJo5u1Xq7k9m9K57\n"
124 "8wIDAQAB\n"
125 "-----END PUBLIC KEY-----\n";
126
127 const char *priv_pem =
128 "-----BEGIN PRIVATE KEY-----\n"
129 "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCgYvoisJIDOeYg\n"
130 "jMF6ywiZbu085TLvy5ZMhq5vfYqdgefvwpemutnfKSnpYOs5B4yO/gAD7XiYluDv\n"
131 "tqlVhfISeQV04xrWGzNImenpwm/HsgueAu8VTHNtWSL96G+BLedGTrs2NqX6cxN7\n"
132 "yGl7dQpB5X8iP4XSvpjP3Vb7gs+adwCJR6xFkt60jYFmwrAdhEzOeakhimi5rU21\n"
133 "LxCkRdEyaxS57X15L9dEA+aYJ+dvkFfZOfTqIKmTrA75F8yj161xflwtIC4hgRBg\n"
134 "K9Xb/RdN8TDrTu+20E3RjngutU4qejW9Fd3mzHJGV8HRYvjYXhUblN9wmjm7Veru\n"
135 "T2b0rnvzAgMBAAECggEBAIwHvoJ5DRJ6A50Zp3dROxHTEphfOEi6xF/OGxBGWLbK\n"
136 "C7l+eS9d5gj8BJa5QsXI/IR/6X2EYQ1AdeV04oVD7CUKuqPiALU8jFrv3pV0aGm+\n"
137 "3nu37gv3crPe5jkvLeNoM4tkA/oCXom63SDuyoG6nxkHiSdatLlaJUse4em3vRAL\n"
138 "QivziZIMyswcleMe0xAoMi7LO+nUFFxBS8/xGya0vsU0dsMQEl1SRITv1VCXmPQD\n"
139 "T4dEI4+1cufv6Ax0EDbFKmnjyiGTjOeQKrGIqETUSQolbg5PgL1XZehaaxM822OY\n"
140 "Qpnp5T0XhUEmVrOb2Wrboj+dC/2tgAN/fWXjAAxnm2ECgYEA02UTZuZ+QnD6tqo3\n"
141 "/y3n5kaM9uA2mdOIqgECI9psGF1IBIC/iP2diKyuvmQL8hzymComb5YzZl3TOAga\n"
142 "WHQYbIeU3JhnYTG75/Dv5Zh32H4NjkIJHT2/8LUM25Ove9u6QAniVgIQpBZ47LjX\n"
143 "9jHjTYCW5n79qNSfu0egYJUvypECgYEAwjqWzzEINqnX/xIVCoB4XpuDuSdkM0JW\n"
144 "MZDIH9xHjZPp07/5XYEoITylk6Zwbh+djvWDNP4gzPtuK26VsqrNxoWMsFZeXn6U\n"
145 "xSOYL2UNCZiOgchdZCOr+6r8LRUuo8xHjbawVoJVK1+tZ2WsR3ilt3Gw34O8Z5ep\n"
146 "f4v7GOXw+EMCgYAUHjFrgJIRhqkFi0uK+HZyXtJ5iDsKBqyh6Tin6tiQtQfujcYs\n"
147 "pl5ArJZwvhq47vJTcud3hSbdHh7E3ViMhHfylDChkct833vPhgl+ozT8oHpvyG8P\n"
148 "nlnO8ZwIpZR0yCOAhrBImSe2RgE6HhlHb9X/ATbbNsizMZEGBLoJlwkWUQKBgQCy\n"
149 "4U7fh2LvJUF+82JZh7RUPZn1Pmg0JVZI0/TcEv37UEy77kR1b2xMIBTGhTVq1sc/\n"
150 "ULIEbkA7SR1P9sr7//8AZSMLjJ/hG2dcoMmabNCzE8O7l5MblRbh87nIs4d+57bG\n"
151 "t4h0RBi4l6eWYLdoI59L8fNaB3PPXIiIpZ0eczeZDQKBgQC2vuFYpUZqDb9CaJsn\n"
152 "Luee6P6n5v3ZBTAT4E+GG1kWS28BiebcCuLKNAY4ZtLo08ozaTWcMxooOTeka2ux\n"
153 "fQDE4M/LTNpam8QOJ2hqECF5a0uBYNcbmaGtfA9KwIgwCZZYuwb5IDq/DRPuR690\n"
154 "i8Kp6jR2wY0suObmZHKvbCB1Dw==\n"
155 "-----END PRIVATE KEY-----\n";
156
157 const char *cert =
158 "-----BEGIN CERTIFICATE-----\n"
159 "MIIDBjCCAe4CCQDcvXBOEVM0UTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE\n"
160 "RTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0\n"
161 "cyBQdHkgTHRkMB4XDTE5MDIyODEwNDkyM1oXDTM1MDgyNzEwNDkyM1owRTELMAkG\n"
162 "A1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0\n"
163 "IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
164 "AKBi+iKwkgM55iCMwXrLCJlu7TzlMu/LlkyGrm99ip2B5+/Cl6a62d8pKelg6zkH\n"
165 "jI7+AAPteJiW4O+2qVWF8hJ5BXTjGtYbM0iZ6enCb8eyC54C7xVMc21ZIv3ob4Et\n"
166 "50ZOuzY2pfpzE3vIaXt1CkHlfyI/hdK+mM/dVvuCz5p3AIlHrEWS3rSNgWbCsB2E\n"
167 "TM55qSGKaLmtTbUvEKRF0TJrFLntfXkv10QD5pgn52+QV9k59OogqZOsDvkXzKPX\n"
168 "rXF+XC0gLiGBEGAr1dv9F03xMOtO77bQTdGOeC61Tip6Nb0V3ebMckZXwdFi+Nhe\n"
169 "FRuU33CaObtV6u5PZvSue/MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAcamUPe8I\n"
170 "nMOHcv9x5lVN1joihVRmKc0QqNLFc6XpJY8+U5rGkZvOcDe9Da8L97wDNXpKmU/q\n"
171 "pprj3rT8l3v0Z5xs8Vdr8lxS6T5NhqQV0UCsn1x14gZJcE48y9/LazYi6Zcar+BX\n"
172 "Am4vewAV3HmQ8X2EctsRhXe4wlAq4slIfEWaaofa8ai7BzO9KwpMLsGPWoNetkB9\n"
173 "19+SFt0lFFOj/6vDw5pCpSd1nQlo1ug69mJYSX/wcGkV4t4LfGhV8jRPDsGs6I5n\n"
174 "ETHSN5KV1XCPYJmRCjFY7sIt1x4zN7JJRO9DVw+YheIlduVfkBiF+GlQgLlFTjrJ\n"
175 "VrpSGMIFSu301A==\n"
176 "-----END CERTIFICATE-----\n";
177
178 char *cert2 = NULL;
179 char *path_list = NULL;
180
181 r = Fapi_Import(context, "myExtPubKey", pub_pem);
182 goto_if_error(r, "Error Fapi_Import", error);
183
184 bufio = BIO_new_mem_buf((void *)priv_pem, strlen(priv_pem));
185 evp_key = PEM_read_bio_PrivateKey(bufio, NULL, NULL, NULL);
186 rsa_key = EVP_PKEY_get1_RSA(evp_key);
187
188
189 if (!bufio || !evp_key || !rsa_key) {
190 LOG_ERROR("Generation of test key failed.");
191 goto error;
192 }
193
194 uint8_t digest[20] = {
195 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e,
196 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d
197 };
198 uint8_t signature[256];
199 unsigned int signatureLength = 256;
200
201 if (!RSA_sign(NID_sha1, digest, 20, signature, &signatureLength, rsa_key)) {
202 LOG_ERROR("Test RSA_sign failed.");
203 goto error;
204 }
205
206 r = Fapi_VerifySignature(context, "/ext/myExtPubKey", digest, 20,
207 signature, 256);
208 goto_if_error(r, "Error Fapi_VerifySignature", error);
209
210 r = Fapi_SetCertificate(context, "/ext/myExtPubKey", cert);
211 goto_if_error(r, "Error Fapi_SetCertificate", error);
212
213 r = Fapi_GetCertificate(context, "/ext/myExtPubKey", &cert2);
214 goto_if_error(r, "Error Fapi_SetCertificate", error);
215
216 if (strcmp(cert, cert2) != 0) {
217 goto_if_error(r, "Different certificates", error);
218 }
219
220 r = Fapi_List(context, "", &path_list);
221 goto_if_error(r, "Error Fapi_List", error);
222
223 /* Test VerfiyQuote in non TPM mode. */
224 r = Fapi_Import(context, "/ext/myExtPubKey", pubkey_pem);
225 goto_if_error(r, "Error Fapi_Import", error);
226
227 r = Fapi_VerifyQuote(context, "/ext/myExtPubKey",
228 qualifying_data, 20, quote_info,
229 test_signature, test_signature_size, NULL);
230 goto_if_error(r, "Error Fapi_Verfiy_Quote", error);
231
232 fprintf(stderr, "\nPathList:\n%s\n", path_list);
233
234 r = Fapi_Delete(context, "/ext");
235 goto_if_error(r, "Error Fapi_Delete", error);
236 if (bufio) {
237 BIO_free(bufio);
238 }
239 if (evp_key) {
240 EVP_PKEY_free(evp_key);
241 }
242 if (rsa_key) {
243 RSA_free(rsa_key);
244 }
245 SAFE_FREE(path_list);
246 SAFE_FREE(cert2);
247 return EXIT_SUCCESS;
248
249 error:
250 Fapi_Delete(context, "/");
251 if (bufio) {
252 BIO_free(bufio);
253 }
254 if (evp_key) {
255 EVP_PKEY_free(evp_key);
256 }
257 if (rsa_key) {
258 RSA_free(rsa_key);
259 }
260 SAFE_FREE(path_list);
261 SAFE_FREE(cert2);
262 return EXIT_FAILURE;
263 }
264
265 int
266 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
267 {
268 return test_fapi_ext_public_key(fapi_context);
269 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11
12 #include "tss2_fapi.h"
13
14 #define LOGMODULE test
15 #include "util/log.h"
16 #include "util/aux_util.h"
17
18 /** Test the FAPI function FAPI_GetRandom and async invocations.
19 *
20 * Tested FAPI commands:
21 * - Fapi_Provision()
22 * - Fapi_GetRandom_Async()
23 * - Fapi_GetRandom_Finish()
24 * - Fapi_GetPollHandles()
25 * - Fapi_GetRandom()
26 * - Fapi_Delete()
27 *
28 * @param[in,out] context The FAPI_CONTEXT.
29 * @retval EXIT_FAILURE
30 * @retval EXIT_SUCCESS
31 */
32 int
33 test_fapi_get_random(FAPI_CONTEXT *context)
34 {
35
36 TSS2_RC r;
37 FAPI_POLL_HANDLE *handles;
38 size_t num_handles;
39 /* Ensure that more than one call of Esys_GetRandom is necessary */
40 size_t bytesRequested = sizeof(TPMU_HA) + 10;
41 uint8_t *randomBytes;
42
43 r = Fapi_Provision(context, NULL, NULL, NULL);
44 goto_if_error(r, "Error Fapi_Provision", error);
45
46 r = Fapi_GetRandom_Async(context, bytesRequested);
47 goto_if_error(r, "GetRandom_Async", error);
48
49 do {
50 r = Fapi_GetPollHandles(context, &handles, &num_handles);
51 if (r == TSS2_RC_SUCCESS) {
52 poll(handles, num_handles, -1);
53 Fapi_Free(handles);
54 } else if (r != TSS2_FAPI_RC_NO_HANDLE) {
55 LOG_ERROR("GetPollHandles failed");
56 goto error;
57 }
58
59 r = Fapi_GetRandom_Finish(context, &randomBytes);
60 } while (r == TSS2_FAPI_RC_TRY_AGAIN);
61 goto_if_error(r, "Error Fapi_GetRandom_Finish", error);
62
63 Fapi_Free(randomBytes);
64
65 r = Fapi_GetRandom(context, bytesRequested, &randomBytes);
66 goto_if_error(r, "Error Fapi_GetRandom", error);
67
68 Fapi_Free(randomBytes);
69
70 /* Cleanup */
71 r = Fapi_Delete(context, "/HS/SRK");
72 goto_if_error(r, "Error Fapi_Delete", error);
73
74 return TSS2_RC_SUCCESS;
75
76 error:
77 Fapi_Delete(context, "/HS/SRK");
78 return EXIT_FAILURE;
79 }
80
81 int
82 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
83 {
84 return test_fapi_get_random(fapi_context);
85 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11
12 #include "tss2_fapi.h"
13
14 #define LOGMODULE test
15 #include "util/log.h"
16 #include "util/aux_util.h"
17
18 /** Test the FAPI functions for GetInfo.
19 *
20 * Tested FAPI commands:
21 * - Fapi_Provision()
22 * - Fapi_GetInfo()
23 * - Fapi_Delete()
24 *
25 * @param[in,out] context The FAPI_CONTEXT.
26 * @retval EXIT_FAILURE
27 * @retval EXIT_SUCCESS
28 */
29 int
30 test_fapi_info(FAPI_CONTEXT *context)
31 {
32
33 TSS2_RC r;
34 char *info = NULL;
35
36 r = Fapi_Provision(context, NULL, NULL, NULL);
37 goto_if_error(r, "Error Fapi_Provision", error);
38
39 r = Fapi_GetInfo(context, &info);
40 goto_if_error(r, "Error Fapi_Provision", error);
41
42 LOG_INFO("%s", info);
43
44 /* Cleanup */
45 r = Fapi_Delete(context, "/HS/SRK");
46 goto_if_error(r, "Error Fapi_Delete", error);
47
48 SAFE_FREE(info);
49 return EXIT_SUCCESS;
50
51 error:
52 Fapi_Delete(context, "/HS/SRK");
53 SAFE_FREE(info);
54 return EXIT_FAILURE;
55 }
56
57 int
58 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
59 {
60 return test_fapi_info(fapi_context);
61 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14
15 #define LOGMODULE test
16 #include "util/log.h"
17 #include "util/aux_util.h"
18
19 #define PASSWORD "abc"
20
21 static TSS2_RC
22 auth_callback(
23 FAPI_CONTEXT *context,
24 char const *description,
25 char **auth,
26 void *userData)
27 {
28 (void)description;
29 (void)userData;
30 *auth = strdup(PASSWORD);
31 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
32 return TSS2_RC_SUCCESS;
33 }
34
35
36 /** Test the FAPI function for changing key authorizations.
37 *
38 * The setting of the authorization callback and usage of the
39 * key with Fapi_Sign afterwards is also tested.
40 *
41 * Tested FAPI commands:
42 * - Fapi_Provision()
43 * - Fapi_CreateKey()
44 * - Fapi_ChangeAuth()
45 * - Fapi_SetAuthCB()
46 * - Fapi_Sign()
47 * - Fapi_Delete()
48 *
49 * @param[in,out] context The FAPI_CONTEXT.
50 * @retval EXIT_FAILURE
51 * @retval EXIT_SUCCESS
52 */
53 int
54 test_fapi_key_change_auth(FAPI_CONTEXT *context)
55 {
56
57 TSS2_RC r;
58 uint8_t *signature = NULL;
59 char *publicKey = NULL;
60
61 r = Fapi_Provision(context, NULL, NULL, NULL);
62
63 goto_if_error(r, "Error Fapi_Provision", error);
64
65 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", "sign,noDa", "", NULL);
66 goto_if_error(r, "Error Fapi_CreateKey", error);
67 size_t signatureSize = 0;
68
69 TPM2B_DIGEST digest = {
70 .size = 20,
71 .buffer = {
72 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
73 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
74 }
75 };
76
77 r = Fapi_ChangeAuth(context, "HS/SRK/mySignKey", PASSWORD);
78 goto_if_error(r, "Error Fapi_Provision", error);
79
80 r = Fapi_SetAuthCB(context, auth_callback, "");
81 goto_if_error(r, "Error SetPolicyAuthCallback", error);
82
83 r = Fapi_Sign(context, "HS/SRK/mySignKey", NULL,
84 &digest.buffer[0], digest.size, &signature, &signatureSize,
85 &publicKey, NULL);
86 goto_if_error(r, "Error Fapi_Provision", error);
87
88 Fapi_Free(publicKey);
89
90 r = Fapi_Delete(context, "/HS/SRK");
91 goto_if_error(r, "Error Fapi_Delete", error);
92
93 SAFE_FREE(signature);
94 return EXIT_SUCCESS;
95
96 error:
97 Fapi_Delete(context, "/HS/SRK");
98 SAFE_FREE(signature);
99 return EXIT_FAILURE;
100 }
101
102 int
103 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
104 {
105 return test_fapi_key_change_auth(fapi_context);
106 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14
15 #define LOGMODULE test
16 #include "util/log.h"
17 #include "util/aux_util.h"
18
19 #ifdef FAPI_PASSWORD
20
21 #define PASSWORD "abc"
22
23 static TSS2_RC
24 auth_callback(
25 FAPI_CONTEXT *context,
26 char const *description,
27 char **auth,
28 void *userData)
29 {
30 (void)description;
31 (void)userData;
32 *auth = strdup(PASSWORD);
33 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
34 return TSS2_RC_SUCCESS;
35 }
36 #else /*FAPI_PASSWORD */
37 #define PASSWORD NULL
38 #endif /* FAPI_PASSWORD */
39
40 #ifdef FAPI_DA
41 #define SIGN_TEMPLATE "sign"
42 #else
43 #define SIGN_TEMPLATE "sign, noDa"
44 #endif
45
46 /** Test the FAPI functions for key creation and usage with noda and da flag.
47 *
48 * Tested FAPI commands:
49 * - Fapi_Provision()
50 * - Fapi_CreateKey()
51 * - Fapi_SetAuthCB()
52 * - Fapi_Sign()
53 * - Fapi_Delete()
54 *
55 * @param[in,out] context The FAPI_CONTEXT.
56 * @retval EXIT_FAILURE
57 * @retval EXIT_SUCCESS
58 */
59 int
60 test_fapi_key_create_ckda_sign(FAPI_CONTEXT *context)
61 {
62 TSS2_RC r;
63
64 uint8_t *signature = NULL;
65 char *publicKey = NULL;
66
67 r = Fapi_Provision(context, NULL, NULL, NULL);
68 goto_if_error(r, "Error Fapi_Provision", error);
69
70 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", SIGN_TEMPLATE, "",
71 PASSWORD);
72 goto_if_error(r, "Error Fapi_CreateKey", error);
73 size_t signatureSize = 0;
74
75 TPM2B_DIGEST digest = {
76 .size = 20,
77 .buffer = {
78 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
79 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
80 }
81 };
82
83 #ifdef FAPI_PASSWORD
84 r = Fapi_SetAuthCB(context, auth_callback, "");
85 goto_if_error(r, "Error SetPolicyAuthCallback", error);
86 #endif
87
88 r = Fapi_Sign(context, "HS/SRK/mySignKey", NULL,
89 &digest.buffer[0], digest.size, &signature, &signatureSize,
90 &publicKey, NULL);
91 goto_if_error(r, "Error Fapi_Sign", error);
92
93 r = Fapi_Delete(context, "/HS/SRK");
94 goto_if_error(r, "Error Fapi_Delete", error);
95
96 SAFE_FREE(signature);
97 SAFE_FREE(publicKey);
98
99 return EXIT_SUCCESS;
100
101 error:
102 SAFE_FREE(signature);
103 SAFE_FREE(publicKey);
104 return EXIT_FAILURE;
105 }
106
107 int
108 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
109 {
110 return test_fapi_key_create_ckda_sign(fapi_context);
111 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16
17 #include "tss2_fapi.h"
18
19 #define LOGMODULE test
20 #include "util/log.h"
21 #include "util/aux_util.h"
22 #include "test-fapi.h"
23
24 #ifdef TEST_PASSWORD
25 #define PASSWORD "abc"
26 #else
27 #define PASSWORD ""
28 #endif
29
30 static TSS2_RC
31 auth_callback(
32 FAPI_CONTEXT *context,
33 char const *description,
34 char **auth,
35 void *userData)
36 {
37 (void)description;
38 (void)userData;
39 *auth = strdup(PASSWORD);
40 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
41 return TSS2_RC_SUCCESS;
42 }
43 #define SIGN_TEMPLATE "sign,noDa"
44
45 /** Test several FAPI policies by usage of signing key.
46 *
47 * Which test case will be executed is determined by the compiler switches:
48 * TEST_POLICY_PASSWORD, TEST_POLICY_AUTH_VALUE, TEST_POLICY_LOCALITY
49 * TEST_POLICY_PHYSICAL_PRESENCE, TEST_POLICY_COMMAND_CODE, TEST_POLICY_COUNTERTIMER.
50 *
51 * Tested FAPI commands:
52 * - Fapi_Provision()
53 * - Fapi_Import()
54 * - Fapi_CreateKey()
55 * - Fapi_SetAuthCB()
56 * - Fapi_Sign()
57 * - Fapi_Delete()
58 *
59 * Tested Policies:
60 * - PolicyPassword
61 * - PolicyAuthValue
62 * - PolicyLocality
63 * - PolicyPhysicalPresence
64 * - PolicyCommandCode
65 * - PolicyCounterTimer
66 *
67 * @param[in,out] context The FAPI_CONTEXT.
68 * @retval EXIT_FAILURE
69 * @retval EXIT_SUCCESS
70 */
71 int
72 test_fapi_key_create_policies_sign(FAPI_CONTEXT *context)
73 {
74 TSS2_RC r;
75
76 #if defined(TEST_POLICY_PASSWORD)
77 char *policy_name = "/policy/pol_password";
78 char *policy_file = FAPI_POLICIES "/policy/pol_password.json";
79 #elif defined(TEST_POLICY_AUTH_VALUE)
80 char *policy_name = "/policy/pol_auth_value";
81 char *policy_file = FAPI_POLICIES "/policy/pol_auth_value.json";
82 #elif defined(TEST_POLICY_LOCALITY)
83 char *policy_name = "/policy/pol_locality";
84 char *policy_file = FAPI_POLICIES "/policy/pol_locality.json";
85 #elif defined(TEST_POLICY_PHYSICAL_PRESENCE)
86 char *policy_name = "/policy/pol_physical_presence";
87 char *policy_file = FAPI_POLICIES "/policy/pol_physical_presence.json";
88 #elif defined(TEST_POLICY_COMMAND_CODE)
89 char *policy_name = "/policy/pol_command_code";
90 char *policy_file = FAPI_POLICIES "/policy/pol_command_code.json";
91 #elif defined(TEST_POLICY_COUNTERTIMER)
92 char *policy_name = "/policy/pol_countertimer";
93 char *policy_file = FAPI_POLICIES "/policy/pol_countertimer.json";
94 #else
95 #error "Please define POLICY_PASSWORD,_AUTH_VALUE,_LOCALITY,_PHYSICAL_PRESENCE,_COMMAND_CODE,_COUNTERTIMER"
96 #endif
97
98 FILE *stream = NULL;
99 uint8_t *signature =NULL;
100 char *publicKey = NULL;
101 char *json_policy = NULL;
102 long policy_size;
103
104 r = Fapi_Provision(context, NULL, NULL, NULL);
105 goto_if_error(r, "Error Fapi_Provision", error);
106
107 r = pcr_reset(context, 16);
108 goto_if_error(r, "Error pcr_reset", error);
109
110 stream = fopen(policy_file, "r");
111 if (!stream) {
112 LOG_ERROR("File %s does not exist", policy_file);
113 goto error;
114 }
115 fseek(stream, 0L, SEEK_END);
116 policy_size = ftell(stream);
117 fclose(stream);
118 json_policy = malloc(policy_size + 1);
119 goto_if_null(json_policy,
120 "Could not allocate memory for the JSON policy",
121 TSS2_FAPI_RC_MEMORY, error);
122 stream = fopen(policy_file, "r");
123 ssize_t ret = read(fileno(stream), json_policy, policy_size);
124 if (ret != policy_size) {
125 LOG_ERROR("IO error %s.", policy_file);
126 goto error;
127 }
128 json_policy[policy_size] = '\0';
129
130 r = Fapi_Import(context, policy_name, json_policy);
131 goto_if_error(r, "Error Fapi_Import", error);
132
133 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", SIGN_TEMPLATE,
134 policy_name, PASSWORD);
135 goto_if_error(r, "Error Fapi_CreateKey", error);
136 size_t signatureSize = 0;
137
138 TPM2B_DIGEST digest = {
139 .size = 20,
140 .buffer = {
141 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
142 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
143 }
144 };
145
146 r = Fapi_SetAuthCB(context, auth_callback, "");
147 goto_if_error(r, "Error SetPolicyAuthCallback", error);
148
149 r = Fapi_Sign(context, "HS/SRK/mySignKey", NULL,
150 &digest.buffer[0], digest.size, &signature, &signatureSize,
151 &publicKey, NULL);
152
153 #if defined(TEST_POLICY_PHYSICAL_PRESENCE)
154 if ((r & ~TPM2_RC_N_MASK) == TPM2_RC_PP) {
155 LOG_WARNING("Test requires physical presence.");
156 goto skip;
157 } else if (r == TPM2_RC_COMMAND_CODE) {
158 LOG_WARNING("Command not supported, probably PolicyPhysicalPresence");
159 goto skip;
160 }
161 #endif /* TEST_POLICY_PHYSICAL_PRESENCE */
162 goto_if_error(r, "Error Fapi_Sign", error);
163
164 r = Fapi_Delete(context, "/HS/SRK/mySignKey");
165 goto_if_error(r, "Error Fapi_Delete", error);
166
167 r = Fapi_Delete(context, "/HS/SRK");
168 goto_if_error(r, "Error Fapi_Delete", error);
169
170 SAFE_FREE(json_policy);
171 SAFE_FREE(signature);
172 SAFE_FREE(publicKey);
173 return EXIT_SUCCESS;
174
175 #if defined(TEST_POLICY_PHYSICAL_PRESENCE)
176 r = Fapi_Delete(context, "/HS/SRK/mySignKey");
177 goto_if_error(r, "Error Fapi_Delete", error);
178
179 r = Fapi_Delete(context, "/HS/SRK");
180 goto_if_error(r, "Error Fapi_Delete", error);
181
182 skip:
183 Fapi_Delete(context, "/HS/SRK");
184 SAFE_FREE(json_policy);
185 SAFE_FREE(signature);
186 SAFE_FREE(publicKey);
187 return EXIT_SKIP;
188 #endif /* TEST_POLICY_PHYSICAL_PRESENCE */
189
190 error:
191 Fapi_Delete(context, "/HS/SRK");
192
193 SAFE_FREE(json_policy);
194 SAFE_FREE(signature);
195 SAFE_FREE(publicKey);
196 return EXIT_FAILURE;
197 }
198
199 int
200 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
201 {
202 return test_fapi_key_create_policies_sign(fapi_context);
203 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17
18
19 #include "tss2_fapi.h"
20 #include "tss2_esys.h"
21 #include "tss2_tcti.h"
22
23 #include "test-fapi.h"
24
25 #define LOGMODULE test
26 #include "util/log.h"
27 #include "util/aux_util.h"
28
29 #define NV_SIZE 34
30 #define PASSWORD ""
31 #define SIGN_TEMPLATE "sign"
32
33 static TSS2_RC
34 check_tpm_cmd(FAPI_CONTEXT *context, TPM2_CC command_code)
35 {
36 TSS2_RC r;
37 TSS2_TCTI_CONTEXT *tcti;
38 ESYS_CONTEXT *esys;
39 TPMS_CAPABILITY_DATA *cap_data;
40
41 r = Fapi_GetTcti(context, &tcti);
42 goto_if_error(r, "Error Fapi_GetTcti", error);
43
44 r = Esys_Initialize(&esys, tcti, NULL);
45 goto_if_error(r, "Error Fapi_GetTcti", error);
46
47 r = Esys_GetCapability(esys,
48 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
49 TPM2_CAP_COMMANDS, command_code, 1, NULL, &cap_data);
50 Esys_Finalize(&esys);
51 return_if_error(r, "Error: GetCapabilities");
52
53 if ((cap_data->data.command.commandAttributes[0] & TPMA_CC_COMMANDINDEX_MASK) ==
54 command_code) {
55 free(cap_data);
56 return TSS2_RC_SUCCESS;
57 } else {
58 free(cap_data);
59 return TSS2_FAPI_RC_NOT_IMPLEMENTED;
60 }
61
62 error:
63 return r;
64 }
65
66 static char *
67 read_policy(FAPI_CONTEXT *context, char *policy_name)
68 {
69 FILE *stream = NULL;
70 long policy_size;
71 char *json_policy = NULL;
72 char policy_file[1024];
73
74 if (snprintf(&policy_file[0], 1023, TOP_SOURCEDIR "/test/data/fapi/%s.json", policy_name) < 0)
75 return NULL;
76
77 stream = fopen(policy_file, "r");
78 if (!stream) {
79 LOG_ERROR("File %s does not exist", policy_file);
80 return NULL;
81 }
82 fseek(stream, 0L, SEEK_END);
83 policy_size = ftell(stream);
84 fclose(stream);
85 json_policy = malloc(policy_size + 1);
86 stream = fopen(policy_file, "r");
87 ssize_t ret = read(fileno(stream), json_policy, policy_size);
88 if (ret != policy_size) {
89 LOG_ERROR("IO error %s.", policy_file);
90 return NULL;
91 }
92 json_policy[policy_size] = '\0';
93 return json_policy;
94 }
95
96 /** Test the FAPI key signing with PolicyAuthorizeNV.
97 *
98 * Tested FAPI commands:
99 * - Fapi_GetTcti()
100 * - Fapi_Provision()
101 * - Fapi_CreateNv()
102 * - Fapi_Import()
103 * - Fapi_WriteAuthorizeNv()
104 * - Fapi_CreateKey()
105 * - Fapi_Sign()
106 * - Fapi_Delete()
107 *
108 * Tested Policies:
109 * - PolicyAuthorizeNv
110 *
111 * @param[in,out] context The FAPI_CONTEXT.
112 * @retval EXIT_FAILURE
113 * @retval EXIT_SUCCESS
114 */
115 int
116 test_fapi_key_create_policy_authorize_nv(FAPI_CONTEXT *context)
117 {
118 TSS2_RC r;
119 char *nvPathPolicy = "/nv/Owner/myNV";
120 char *policy_authorize_nv = "/policy/pol_authorize_nv";
121 char *policy_pcr2 = "/policy/pol_pcr16_0";
122 char *json_policy = NULL;
123
124 uint8_t *signature = NULL;
125 char *publicKey = NULL;
126
127 if (check_tpm_cmd(context, TPM2_CC_PolicyAuthorizeNV) != TPM2_RC_SUCCESS) {
128 LOG_WARNING("Command PolicyAuthorizeNV not available.");
129 return EXIT_SKIP;
130 }
131
132 r = Fapi_Provision(context, NULL, NULL, NULL);
133 goto_if_error(r, "Error Fapi_Provision", error);
134
135 /* Create NV object for storing the policy */
136 r = Fapi_CreateNv(context, nvPathPolicy, "noda", 34, "", "");
137 goto_if_error(r, "Error Fapi_CreateNv", error);
138
139 r = pcr_reset(context, 16);
140 goto_if_error(r, "Error pcr_reset", error);
141
142 json_policy = read_policy(context, policy_authorize_nv);
143 if (!json_policy)
144 goto error;
145
146 r = Fapi_Import(context, policy_authorize_nv, json_policy);
147 goto_if_error(r, "Error Fapi_Import", error);
148 SAFE_FREE(json_policy);
149
150 json_policy = read_policy(context, policy_pcr2);
151 if (!json_policy)
152 goto error;
153
154 r = Fapi_Import(context, policy_pcr2, json_policy);
155 goto_if_error(r, "Error Fapi_Import", error);
156
157 r = Fapi_WriteAuthorizeNv(context,nvPathPolicy, policy_pcr2);
158 goto_if_error(r, "Error Fapi_WriteAuthorizeNv", error);
159
160 r = Fapi_CreateKey(context, "/HS/SRK/myPolicySignKey", "sign",
161 "", PASSWORD);
162 goto_if_error(r, "Error Fapi_CreateKey", error);
163
164 r = Fapi_CreateKey(context, "/HS/SRK/mySignKey", SIGN_TEMPLATE,
165 policy_authorize_nv, PASSWORD);
166 goto_if_error(r, "Error Fapi_CreateKey", error);
167
168 size_t signatureSize = 0;
169
170 TPM2B_DIGEST digest = {
171 .size = 20,
172 .buffer = {
173 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
174 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
175 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
176 0x41, 0x42
177 }
178 };
179
180 r = Fapi_Sign(context, "/HS/SRK/mySignKey", NULL,
181 &digest.buffer[0], digest.size, &signature, &signatureSize,
182 &publicKey, NULL);
183 goto_if_error(r, "Error Fapi_Sign", error);
184
185 r = Fapi_Delete(context, nvPathPolicy);
186 goto_if_error(r, "Error Fapi_NV_Undefine", error);
187
188 r = Fapi_Delete(context, "/");
189 goto_if_error(r, "Error Fapi_Delete", error);
190
191 SAFE_FREE(json_policy);
192 SAFE_FREE(signature);
193 SAFE_FREE(publicKey);
194 return EXIT_SUCCESS;
195
196 error:
197 SAFE_FREE(json_policy);
198 SAFE_FREE(signature);
199 SAFE_FREE(publicKey);
200 return EXIT_FAILURE;
201 }
202
203 int
204 test_invoke_fapi(FAPI_CONTEXT *context)
205 {
206 return test_fapi_key_create_policy_authorize_nv(context);
207 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdbool.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17
18 #include "tss2_fapi.h"
19
20 #include "test-fapi.h"
21
22 #define LOGMODULE test
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 static bool cb_called = false;
27
28 static TSS2_RC
29 branch_callback(
30 FAPI_CONTEXT *context,
31 char const *description,
32 char const **branchNames,
33 size_t numBranches,
34 size_t *selectedBranch,
35 void *userData)
36 {
37 (void) description;
38 (void) userData;
39
40 if (numBranches != 2) {
41 LOG_ERROR("Wrong number of branches");
42 return TSS2_FAPI_RC_GENERAL_FAILURE;
43 }
44
45 if (!strcmp(branchNames[0], "/policy/pol_name_hash"))
46 *selectedBranch = 0;
47 else if (!strcmp(branchNames[1], "/policy/pol_name_hash"))
48 *selectedBranch = 1;
49 else {
50 LOG_ERROR("BranchName not found. Got \"%s\" and \"%s\"",
51 branchNames[0], branchNames[1]);
52 return TSS2_FAPI_RC_GENERAL_FAILURE;
53 }
54
55 cb_called = true;
56
57 return TSS2_RC_SUCCESS;
58 }
59
60 /** Test the FAPI functions for PolicyAuthoirze with signing.
61 *
62 * Tested FAPI commands:
63 * - Fapi_Provision()
64 * - Fapi_SetBranchCB()
65 * - Fapi_Import()
66 * - Fapi_CreateKey()
67 * - Fapi_AuthorizePolicy()
68 * - Fapi_Sign()
69 * - Fapi_List()
70 * - Fapi_Delete()
71 *
72 * Tested Policies:
73 * - PolicyNameHash
74 * - PolicyAuthorize
75 * - PolicyCpHash (Not entered, only as alternative branch)
76 *
77 * @param[in,out] context The FAPI_CONTEXT.
78 * @retval EXIT_FAILURE
79 * @retval EXIT_SUCCESS
80 */
81 int
82 test_fapi_key_create_policy_authorize_sign(FAPI_CONTEXT *context)
83 {
84 TSS2_RC r;
85 char *policy_name_hash = "/policy/pol_name_hash";
86 char *policy_file_name_hash = TOP_SOURCEDIR "/test/data/fapi/policy/pol_name_hash.json";
87
88 /* This policy cannot succeed, but that's the intention. We authorize it but then choose
89 the other policy from branch selection. */
90 char *policy_cphash = "/policy/pol_cphash";
91 char *policy_file_cphash = TOP_SOURCEDIR "/test/data/fapi/policy/pol_cphash.json";
92 char *policy_name_authorize = "/policy/pol_authorize";
93 char *policy_file_authorize = TOP_SOURCEDIR "/test/data/fapi/policy/pol_authorize.json";
94 char *policy_name_authorize_outer = "/policy/pol_authorize_outer";
95 char *policy_file_authorize_outer = TOP_SOURCEDIR
96 "/test/data/fapi/policy/pol_authorize_outer.json";
97 uint8_t policyRef[] = { 1, 2, 3, 4, 5 };
98 FILE *stream = NULL;
99 char *json_policy = NULL;
100 long policy_size;
101
102 uint8_t *signature = NULL;
103 char *publicKey = NULL;
104 char *pathList = NULL;
105
106
107 r = Fapi_Provision(context, NULL, NULL, NULL);
108 goto_if_error(r, "Error Fapi_Provision", error);
109
110 r = pcr_reset(context, 16);
111 goto_if_error(r, "Error pcr_reset", error);
112
113 r = Fapi_SetBranchCB(context, branch_callback, NULL);
114 goto_if_error(r, "Error SetPolicybranchselectioncallback", error);
115
116 /* Read in the first policy */
117 stream = fopen(policy_file_name_hash, "r");
118 if (!stream) {
119 LOG_ERROR("File %s does not exist", policy_file_name_hash);
120 goto error;
121 }
122 fseek(stream, 0L, SEEK_END);
123 policy_size = ftell(stream);
124 fclose(stream);
125 json_policy = malloc(policy_size + 1);
126 goto_if_null(json_policy,
127 "Could not allocate memory for the JSON policy",
128 TSS2_FAPI_RC_MEMORY, error);
129 stream = fopen(policy_file_name_hash, "r");
130 ssize_t ret = read(fileno(stream), json_policy, policy_size);
131 if (ret != policy_size) {
132 LOG_ERROR("IO error %s.", policy_file_name_hash);
133 goto error;
134 }
135 json_policy[policy_size] = '\0';
136
137 r = Fapi_Import(context, policy_name_hash, json_policy);
138 SAFE_FREE(json_policy);
139 goto_if_error(r, "Error Fapi_List", error);
140
141 /* Read in the second policy */
142 stream = fopen(policy_file_cphash, "r");
143 if (!stream) {
144 LOG_ERROR("File %s does not exist", policy_file_name_hash);
145 goto error;
146 }
147 fseek(stream, 0L, SEEK_END);
148 policy_size = ftell(stream);
149 fclose(stream);
150 json_policy = malloc(policy_size + 1);
151 goto_if_null(json_policy,
152 "Could not allocate memory for the JSON policy",
153 TSS2_FAPI_RC_MEMORY, error);
154 stream = fopen(policy_file_cphash, "r");
155 ret = read(fileno(stream), json_policy, policy_size);
156 if (ret != policy_size) {
157 LOG_ERROR("IO error %s.", policy_file_name_hash);
158 goto error;
159 }
160 json_policy[policy_size] = '\0';
161
162 r = Fapi_Import(context, policy_cphash, json_policy);
163 SAFE_FREE(json_policy);
164 goto_if_error(r, "Error Fapi_List", error);
165
166 /* Read in the third policy */
167 stream = fopen(policy_file_authorize, "r");
168 if (!stream) {
169 LOG_ERROR("File %s does not exist", policy_file_authorize);
170 goto error;
171 }
172 fseek(stream, 0L, SEEK_END);
173 policy_size = ftell(stream);
174 fclose(stream);
175 json_policy = malloc(policy_size + 1);
176 goto_if_null(json_policy,
177 "Could not allocate memory for the JSON policy",
178 TSS2_FAPI_RC_MEMORY, error);
179 stream = fopen(policy_file_authorize, "r");
180 ret = read(fileno(stream), json_policy, policy_size);
181 if (ret != policy_size) {
182 LOG_ERROR("IO error %s.", policy_file_authorize);
183 goto error;
184 }
185 json_policy[policy_size] = '\0';
186
187 r = Fapi_Import(context, policy_name_authorize, json_policy);
188 SAFE_FREE(json_policy);
189 goto_if_error(r, "Error Fapi_Import", error);
190
191 /* Read in the fourth policy */
192 stream = fopen(policy_file_authorize_outer, "r");
193 if (!stream) {
194 LOG_ERROR("File %s does not exist", policy_file_authorize_outer);
195 goto error;
196 }
197 fseek(stream, 0L, SEEK_END);
198 policy_size = ftell(stream);
199 fclose(stream);
200 json_policy = malloc(policy_size + 1);
201 goto_if_null(json_policy,
202 "Could not allocate memory for the JSON policy",
203 TSS2_FAPI_RC_MEMORY, error);
204 stream = fopen(policy_file_authorize_outer, "r");
205 ret = read(fileno(stream), json_policy, policy_size);
206 if (ret != policy_size) {
207 LOG_ERROR("IO error %s.", policy_file_authorize_outer);
208 goto error;
209 }
210 json_policy[policy_size] = '\0';
211
212 r = Fapi_Import(context, policy_name_authorize_outer, json_policy);
213 SAFE_FREE(json_policy);
214 goto_if_error(r, "Error Fapi_Import", error);
215
216 /* Create keys and use them to authorize the authorize policy */
217 r = Fapi_CreateKey(context, "HS/SRK/myPolicySignKeyOuter", "sign,noDa",
218 "", NULL);
219 goto_if_error(r, "Error Fapi_CreateKey", error);
220
221 /* Create keys and use them to authorize policies */
222 r = Fapi_CreateKey(context, "HS/SRK/myPolicySignKey", "sign,noDa",
223 "", NULL);
224 goto_if_error(r, "Error Fapi_CreateKey", error);
225
226 /* Create the actual key */
227 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", "sign, noda",
228 policy_name_authorize_outer, NULL);
229 goto_if_error(r, "Error Fapi_CreateKey", error);
230
231 /* Authorize the policies in sequence. */
232 r = Fapi_AuthorizePolicy(context, policy_name_authorize,
233 "HS/SRK/myPolicySignKeyOuter", NULL, 0);
234 goto_if_error(r, "Authorize policy", error);
235
236 r = Fapi_AuthorizePolicy(context, policy_name_hash,
237 "HS/SRK/myPolicySignKey", policyRef, sizeof(policyRef));
238 goto_if_error(r, "Authorize policy", error);
239
240 r = Fapi_AuthorizePolicy(context, policy_cphash,
241 "HS/SRK/myPolicySignKey", policyRef, sizeof(policyRef));
242 goto_if_error(r, "Authorize policy", error);
243
244 /* The policy is authorized twice with idfferent keys in order to test the code that
245 stores multiple authorizations inside the policy statements. */
246 r = Fapi_CreateKey(context, "HS/SRK/myPolicySignKey2", "sign,noDa",
247 "", NULL);
248 goto_if_error(r, "Error Fapi_CreateKey", error);
249
250 /* Use the key */
251 size_t signatureSize = 0;
252
253 TPM2B_DIGEST digest = {
254 .size = 32,
255 .buffer = {
256 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
257 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
258 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
259 0x41, 0x42
260 }
261 };
262
263 r = Fapi_Sign(context, "HS/SRK/mySignKey", NULL,
264 &digest.buffer[0], digest.size, &signature, &signatureSize,
265 &publicKey, NULL);
266 goto_if_error(r, "Error Fapi_Sign", error);
267
268 r = Fapi_List(context, "/", &pathList);
269 goto_if_error(r, "Error Fapi_List", error);
270 SAFE_FREE(pathList);
271
272 r = Fapi_List(context, "/SRK/", &pathList);
273 goto_if_error(r, "Error Fapi_List", error);
274 fprintf(stderr, "\n%s\n", pathList);
275 SAFE_FREE(pathList);
276
277 r = Fapi_List(context, "/HS/", &pathList);
278 goto_if_error(r, "Error Fapi_List", error);
279 fprintf(stderr, "\n%s\n", pathList);
280 SAFE_FREE(pathList);
281
282 LOG_WARNING("Next is a failure-test, and we expect errors in the log");
283 r = Fapi_List(context, "XXX", &pathList);
284 if (r == TSS2_RC_SUCCESS) {
285 LOG_ERROR("Path XXX was found");
286 goto error;
287 }
288 SAFE_FREE(pathList);
289
290 r = Fapi_List(context, "/HS/", &pathList);
291 goto_if_error(r, "Error Fapi_List", error);
292 fprintf(stderr, "\n%s\n", pathList);
293 SAFE_FREE(pathList);
294
295 /* Cleanup */
296 r = Fapi_Delete(context, "/HS/SRK");
297 goto_if_error(r, "Error Fapi_Delete", error);
298
299 SAFE_FREE(signature);
300 SAFE_FREE(publicKey);
301
302 if (!cb_called) {
303 LOG_ERROR("Branch selection callback was not called.");
304 return EXIT_FAILURE;
305 }
306
307 return EXIT_SUCCESS;
308
309 error:
310 SAFE_FREE(json_policy);
311 SAFE_FREE(signature);
312 SAFE_FREE(publicKey);
313 SAFE_FREE(pathList);
314 Fapi_Delete(context, "/HS/SRK");
315 return EXIT_FAILURE;
316 }
317
318 int
319 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
320 {
321 return test_fapi_key_create_policy_authorize_sign(fapi_context);
322 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15
16 #include "tss2_fapi.h"
17
18 #define LOGMODULE test
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22 #define SIGN_TEMPLATE "sign,noDa"
23 #define PASSWORD NULL
24
25 #define NV_SIZE 4
26
27 /** Test the FAPI functions for NV writing and key usage.
28 *
29 * Tested FAPI commands:
30 * - Fapi_Provision()
31 * - Fapi_CreateKey()
32 * - Fapi_NvWrite()
33 * - Fapi_Import()
34 * - Fapi_Sign()
35 * - Fapi_Delete()
36 *
37 * Tested Policies:
38 * - PolicyNv
39 *
40 * @param[in,out] context The FAPI_CONTEXT.
41 * @retval EXIT_FAILURE
42 * @retval EXIT_SUCCESS
43 */
44 int
45 test_fapi_key_create_policy_nv_sign(FAPI_CONTEXT *context)
46 {
47 TSS2_RC r;
48 char *policy_name = "/policy/pol_nv";
49 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_nv.json";;
50 FILE *stream = NULL;
51 char *json_policy = NULL;
52 uint8_t *signature = NULL;
53 char *publicKey = NULL;
54 long policy_size;
55 char *nvPathOrdinary = "/nv/Owner/myNV";
56 uint8_t data_nv[NV_SIZE] = { 1, 2, 3, 4 };
57
58 r = Fapi_Provision(context, NULL, NULL, NULL);
59 goto_if_error(r, "Error Fapi_Provision", error);
60
61 r = Fapi_CreateNv(context, nvPathOrdinary, "noda", 4, "", "");
62 goto_if_error(r, "Error Fapi_CreateNv", error);
63
64 r = Fapi_NvWrite(context, nvPathOrdinary, &data_nv[0], NV_SIZE);
65 goto_if_error(r, "Error Fapi_NvWrite", error);
66
67 stream = fopen(policy_file, "r");
68 if (!stream) {
69 LOG_ERROR("File %s does not exist", policy_file);
70 goto error;
71 }
72 fseek(stream, 0L, SEEK_END);
73 policy_size = ftell(stream);
74 fclose(stream);
75 json_policy = malloc(policy_size + 1);
76 goto_if_null(json_policy,
77 "Could not allocate memory for the JSON policy",
78 TSS2_FAPI_RC_MEMORY, error);
79 stream = fopen(policy_file, "r");
80 ssize_t ret = read(fileno(stream), json_policy, policy_size);
81 if (ret != policy_size) {
82 LOG_ERROR("IO error %s.", policy_file);
83 goto error;
84 }
85 json_policy[policy_size] = '\0';
86
87 r = Fapi_Import(context, policy_name, json_policy);
88 goto_if_error(r, "Error Fapi_Import", error);
89
90 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", SIGN_TEMPLATE,
91 policy_name, PASSWORD);
92 goto_if_error(r, "Error Fapi_CreateKey", error);
93 size_t signatureSize = 0;
94
95 TPM2B_DIGEST digest = {
96 .size = 20,
97 .buffer = {
98 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
99 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
100 }
101 };
102
103 r = Fapi_Sign(context, "HS/SRK/mySignKey", NULL,
104 &digest.buffer[0], digest.size, &signature, &signatureSize,
105 &publicKey, NULL);
106 goto_if_error(r, "Error Fapi_Sign", error);
107
108 r = Fapi_Delete(context, nvPathOrdinary);
109 goto_if_error(r, "Error Fapi_NV_Undefine", error);
110
111 r = Fapi_Delete(context, "/HS/SRK");
112 goto_if_error(r, "Error Fapi_Delete", error);
113
114 SAFE_FREE(signature);
115 SAFE_FREE(publicKey);
116 SAFE_FREE(json_policy);
117 return EXIT_SUCCESS;
118
119 error:
120 SAFE_FREE(signature);
121 SAFE_FREE(publicKey);
122 SAFE_FREE(json_policy);
123 return EXIT_FAILURE;
124 }
125
126 int
127 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
128 {
129 return test_fapi_key_create_policy_nv_sign(fapi_context);
130 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdbool.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17
18 #include "tss2_fapi.h"
19
20 #include "test-fapi.h"
21
22 #define LOGMODULE test
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 #define PASSWORD NULL
27 #define SIGN_TEMPLATE "sign,noDa"
28
29 static bool cb_called = false;
30
31 static TSS2_RC
32 branch_callback(
33 FAPI_CONTEXT *context,
34 char const *description,
35 char const **branchNames,
36 size_t numBranches,
37 size_t *selectedBranch,
38 void *userData)
39 {
40 (void) description;
41 (void) userData;
42
43 if (numBranches != 2) {
44 LOG_ERROR("Wrong number of branches");
45 return TSS2_FAPI_RC_GENERAL_FAILURE;
46 }
47
48 if (!strcmp(branchNames[0], "branch0"))
49 *selectedBranch = 0;
50 else if (!strcmp(branchNames[1], "branch0"))
51 *selectedBranch = 1;
52 else {
53 LOG_ERROR("BranchName not found. Got \"%s\" and \"%s\"",
54 branchNames[0], branchNames[1]);
55 return TSS2_FAPI_RC_GENERAL_FAILURE;
56 }
57
58 cb_called = true;
59 return TSS2_RC_SUCCESS;
60 }
61
62
63 /** Test the FAPI for PolicyOr using signing.
64 *
65 * Tested FAPI commands:
66 * - Fapi_Provision()
67 * - Fapi_Import()
68 * - Fapi_CreateKey()
69 * - Fapi_SetBranchCB()
70 * - Fapi_Sign()
71 * - Fapi_Delete()
72 *
73 * Tested Policies:
74 * - PolicyOr
75 * - PolicyPcr
76 *
77 * @param[in,out] context The FAPI_CONTEXT.
78 * @retval EXIT_FAILURE
79 * @retval EXIT_SUCCESS
80 */
81 int
82 test_fapi_key_create_policy_or_sign(FAPI_CONTEXT *context)
83 {
84 TSS2_RC r;
85 char *policy_name = "/policy/pol_pcr16_0_or";
86 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_pcr16_0_or.json";
87 FILE *stream = NULL;
88 char *json_policy = NULL;
89 uint8_t *signature = NULL;
90 char *publicKey = NULL;
91 long policy_size;
92
93 r = Fapi_Provision(context, NULL, NULL, NULL);
94 goto_if_error(r, "Error Fapi_Provision", error);
95
96 r = pcr_reset(context, 16);
97 goto_if_error(r, "Error pcr_reset", error);
98
99 stream = fopen(policy_file, "r");
100 if (!stream) {
101 LOG_ERROR("File %s does not exist", policy_file);
102 goto error;
103 }
104 fseek(stream, 0L, SEEK_END);
105 policy_size = ftell(stream);
106 fclose(stream);
107 json_policy = malloc(policy_size + 1);
108 goto_if_null(json_policy,
109 "Could not allocate memory for the JSON policy",
110 TSS2_FAPI_RC_MEMORY, error);
111 stream = fopen(policy_file, "r");
112 ssize_t ret = read(fileno(stream), json_policy, policy_size);
113 if (ret != policy_size) {
114 LOG_ERROR("IO error %s.", policy_file);
115 goto error;
116 }
117 json_policy[policy_size] = '\0';
118
119 r = Fapi_Import(context, policy_name, json_policy);
120 goto_if_error(r, "Error Fapi_Import", error);
121
122 r = Fapi_CreateKey(context, "/HS/SRK/mySignKey", SIGN_TEMPLATE,
123 policy_name, PASSWORD);
124 goto_if_error(r, "Error Fapi_CreateKey", error);
125 size_t signatureSize = 0;
126
127 TPM2B_DIGEST digest = {
128 .size = 20,
129 .buffer = {
130 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
131 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
132 }
133 };
134
135 r = Fapi_SetBranchCB(context, branch_callback, NULL);
136 goto_if_error(r, "Error SetPolicybranchselectioncallback", error);
137
138 r = Fapi_Sign(context, "/HS/SRK/mySignKey", NULL,
139 &digest.buffer[0], digest.size, &signature, &signatureSize,
140 &publicKey, NULL);
141 goto_if_error(r, "Error Fapi_Sign", error);
142
143 r = Fapi_Delete(context, "/HS/SRK");
144 goto_if_error(r, "Error Fapi_Delete", error);
145
146 SAFE_FREE(json_policy);
147 SAFE_FREE(signature);
148 SAFE_FREE(publicKey);
149
150 if (!cb_called) {
151 LOG_ERROR("Branch selection callback was not called.");
152 return EXIT_FAILURE;
153 }
154
155 return EXIT_SUCCESS;
156
157 error:
158 SAFE_FREE(json_policy);
159 SAFE_FREE(signature);
160 SAFE_FREE(publicKey);
161 return EXIT_FAILURE;
162 }
163
164 int
165 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
166 {
167 return test_fapi_key_create_policy_or_sign(fapi_context);
168 }
0 /* SPDX-License-Identifier: BSD-2 */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11
12 #include "tss2_fapi.h"
13 #include "fapi_util.h"
14 #include "fapi_int.h"
15
16 #include "esys_iutil.h"
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 #define PASSWORD "abc"
22
23 static TSS2_RC
24 auth_callback(
25 FAPI_CONTEXT *context,
26 char const *description,
27 char **auth,
28 void *userData)
29 {
30 (void)description;
31 (void)userData;
32 *auth = strdup(PASSWORD);
33 return TSS2_RC_SUCCESS;
34 }
35 #define SIGN_TEMPLATE "T_RSA_SIGN"
36 #define PROFILE "P_RSA"
37 #define PROFILE_DIR ""
38
39
40 /** Test the FAPI functions for PolicyImport and PolicyPassword callbacks.
41 *
42 * Tested FAPI commands:
43 * - Fapi_Provision()
44 * - Fapi_PolicyImport()
45 * - Fapi_Key_Create()
46 * - Fapi_SetPolicyAuthCallback()
47 * - Fapi_Key_Sign()
48 * - Fapi_Entity_Delete()
49 * - Fapi_Entities_List()
50 *
51 * Tested Policies:
52 * - PolicyPassword
53 *
54 * @param[in,out] context The FAPI_CONTEXT.
55 * @retval EXIT_FAILURE
56 * @retval EXIT_SUCCESS
57 */
58 int
59 test_fapi_key_create_policy_password_sign(FAPI_CONTEXT *context)
60 {
61 TSS2_RC r;
62 char* policy_name = "policies/pol_password";
63 char* policy_file = NULL;
64 FILE *stream = NULL;
65 char *json_policy = NULL;
66 long policy_size;
67
68 r = Fapi_Provision(context, PROFILE, NULL, NULL, NULL, NULL, NULL);
69 goto_if_error(r, "Error Fapi_Provision", error);
70
71 r = ifapi_asprintf(&policy_file, "%s/%s.json", context->config.profile_dir,
72 policy_name);
73 goto_if_error(r, "Create file name", error);
74
75 r = Fapi_PCR_Reset(context, 16);
76 goto_if_error(r, "Reset PCR 16", error);
77
78 stream = fopen(policy_file, "r");
79 if (!stream) {
80 LOG_ERROR("File %s does not exist", policy_file);
81 goto error;
82 }
83 fseek(stream, 0L, SEEK_END);
84 policy_size = ftell(stream);
85 fclose(stream);
86 json_policy = malloc(policy_size + 1);
87 stream = fopen(policy_file, "r");
88 ssize_t ret = read(fileno(stream), json_policy, policy_size);
89 if (ret != policy_size) {
90 LOG_ERROR("IO error %s.", policy_file);
91 goto error;
92 }
93 json_policy[policy_size] = '\0';
94
95 r = Fapi_PolicyImport(context, policy_name, json_policy);
96 goto_if_error(r, "Error Fapi_Entities_List", error);
97
98 r = Fapi_Key_Create(context, PROFILE_DIR "HS/SNK/mySignKey", SIGN_TEMPLATE,
99 policy_name, PASSWORD);
100 goto_if_error(r, "Error Fapi_Key_Create", error);
101 size_t signatureSize = 0;
102 size_t publicKeySize = 0;
103 size_t certificateSize = 0;
104
105 TPM2B_DIGEST digest = {
106 .size = 20,
107 .buffer = { 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
108 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f }
109 };
110
111 uint8_t *signature;
112 uint8_t *publicKey;
113
114 r = Fapi_SetPolicyAuthCallback(context, auth_callback, "");
115 goto_if_error(r, "Error SetPolicyAuthCallback", error);
116
117 r = Fapi_Key_Sign(context, PROFILE_DIR "HS/SNK/mySignKey",
118 &digest.buffer[0], digest.size, &signature, &signatureSize,
119 &publicKey, &publicKeySize, NULL, &certificateSize);
120 goto_if_error(r, "Error Fapi_Key_Sign", error);
121
122 r = Fapi_Entity_Delete(context, PROFILE "/HE/EK");
123 goto_if_error(r, "Error Fapi_Entity_Delete", error);
124
125 size_t numPaths;
126 char **pathlist;
127
128 r = Fapi_Entities_List(context, PROFILE "/", &pathlist ,&numPaths);
129 goto_if_error(r, "Error Fapi_Entities_List", error);
130
131 /* The two storage keys should remain */
132 if (numPaths != 2) {
133 LOG_ERROR("Wrong number of objects in key store");
134 goto error;
135 }
136
137 return EXIT_SUCCESS;
138
139 error:
140 return EXIT_FAILURE;
141 }
142
143 int
144 test_invoke_fapi(FAPI_CONTEXT * fapi_context) {
145 return test_fapi_key_create_policy_password_sign(fapi_context);
146 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15
16 #include "tss2_fapi.h"
17
18 #include "test-fapi.h"
19 #define LOGMODULE test
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 #define PASSWORD NULL
24 #define SIGN_TEMPLATE "sign,noDa"
25
26
27 /** Test the FAPI functions for PolicyPCR with key creation and usage.
28 *
29 * Tested FAPI commands:
30 * - Fapi_Provision()
31 * - Fapi_Import()
32 * - Fapi_CreateKey()
33 * - Fapi_Sign()
34 * - Fapi_ExportPolicy()
35 * - Fapi_Delete()
36 * - Fapi_Import()
37 * - Fapi_List()
38 *
39 * Tested Policies:
40 * - PolicyPcr (with currentPCRs set)
41 *
42 * @param[in,out] context The FAPI_CONTEXT.
43 * @retval EXIT_FAILURE
44 * @retval EXIT_SUCCESS
45 */
46 int
47 test_fapi_key_create_policy_pcr_sign(FAPI_CONTEXT *context)
48 {
49 TSS2_RC r;
50 char *policy_name = "/policy/pol_pcr16_0";
51 char *policy_pcr_read = "/policy/pol_pcr16_read";
52 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_pcr16_0.json";
53 char *policy_pcr_read_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_pcr16_read.json";
54 FILE *stream = NULL;
55 char *json_policy = NULL;
56 long policy_size;
57
58 uint8_t *signature = NULL;
59 char *publicKey = NULL;
60 char *policy = NULL;
61 char *path_list = NULL;
62
63 r = Fapi_Provision(context, NULL, NULL, NULL);
64 goto_if_error(r, "Error Fapi_Provision", error);
65
66 r = pcr_reset(context, 16);
67 goto_if_error(r, "Error pcr_reset", error);
68
69 stream = fopen(policy_file, "r");
70 if (!stream) {
71 LOG_ERROR("File %s does not exist", policy_file);
72 goto error;
73 }
74 fseek(stream, 0L, SEEK_END);
75 policy_size = ftell(stream);
76 fclose(stream);
77 json_policy = malloc(policy_size + 1);
78 goto_if_null(json_policy,
79 "Could not allocate memory for the JSON policy",
80 TSS2_FAPI_RC_MEMORY, error);
81 stream = fopen(policy_file, "r");
82 ssize_t ret = read(fileno(stream), json_policy, policy_size);
83 if (ret != policy_size) {
84 LOG_ERROR("IO error %s.", policy_file);
85 goto error;
86 }
87 json_policy[policy_size] = '\0';
88
89 r = Fapi_Import(context, policy_name, json_policy);
90 goto_if_error(r, "Error Fapi_Import", error);
91
92 r = Fapi_CreateKey(context, "/HS/SRK/mySignKey", SIGN_TEMPLATE,
93 policy_name, PASSWORD);
94 goto_if_error(r, "Error Fapi_CreateKey", error);
95 size_t signatureSize = 0;
96
97 TPM2B_DIGEST digest = {
98 .size = 20,
99 .buffer = {
100 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
101 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
102 }
103 };
104
105 r = Fapi_Sign(context, "/HS/SRK/mySignKey", NULL,
106 &digest.buffer[0], digest.size, &signature, &signatureSize,
107 &publicKey, NULL);
108 goto_if_error(r, "Error Fapi_Sign", error);
109
110 r = Fapi_ExportPolicy(context, "HS/SRK/mySignKey", &policy);
111 goto_if_error(r, "Error Fapi_ExportPolicy", error);
112 fprintf(stderr, "\nPolicy from key:\n%s\n", policy);
113
114 SAFE_FREE(policy);
115
116 r = Fapi_ExportPolicy(context, policy_name, &policy);
117 goto_if_error(r, "Error Fapi_ExportPolicy", error);
118 fprintf(stderr, "\nPolicy from policy file:\n%s\n", policy);
119
120 /* Run test with current PCRs defined in policy */
121
122 r = Fapi_Delete(context, "/HS/SRK/mySignKey");
123 goto_if_error(r, "Error Fapi_Delete", error);
124
125 fclose(stream);
126 stream = fopen(policy_pcr_read_file, "r");
127 if (!stream) {
128 LOG_ERROR("File %s does not exist", policy_pcr_read_file);
129 goto error;
130 }
131 fseek(stream, 0L, SEEK_END);
132 policy_size = ftell(stream);
133 fclose(stream);
134
135 SAFE_FREE(json_policy);
136 SAFE_FREE(signature);
137 SAFE_FREE(publicKey);
138 SAFE_FREE(policy);
139 SAFE_FREE(path_list);
140
141 json_policy = malloc(policy_size + 1);
142 goto_if_null(json_policy,
143 "Could not allocate memory for the JSON policy",
144 TSS2_FAPI_RC_MEMORY, error);
145 stream = fopen(policy_pcr_read_file, "r");
146 ret = read(fileno(stream), json_policy, policy_size);
147 if (ret != policy_size) {
148 LOG_ERROR("IO error %s.", policy_pcr_read_file);
149 goto error;
150 }
151 json_policy[policy_size] = '\0';
152
153 r = Fapi_Import(context, policy_pcr_read, json_policy);
154 goto_if_error(r, "Error Fapi_Import", error);
155
156 r = Fapi_CreateKey(context, "/HS/SRK/mySignKey", SIGN_TEMPLATE,
157 policy_pcr_read, PASSWORD);
158 goto_if_error(r, "Error Fapi_CreateKey", error);
159 signatureSize = 0;
160
161 r = Fapi_Sign(context, "/HS/SRK/mySignKey", NULL,
162 &digest.buffer[0], digest.size, &signature, &signatureSize,
163 &publicKey, NULL);
164 goto_if_error(r, "Error Fapi_Sign", error);
165
166 r = Fapi_ExportPolicy(context, "HS/SRK/mySignKey", &policy);
167 goto_if_error(r, "Error Fapi_ExportPolicy", error);
168 fprintf(stderr, "\nPolicy from key:\n%s\n", policy);
169
170 SAFE_FREE(policy);
171
172 r = Fapi_ExportPolicy(context, policy_pcr_read, &policy);
173 goto_if_error(r, "Error Fapi_ExportPolicy", error);
174 fprintf(stderr, "\nPolicy from policy file:\n%s\n", policy);
175
176 r = Fapi_Delete(context, "/HS/SRK");
177 goto_if_error(r, "Error Fapi_Delete", error);
178
179 r = Fapi_List(context, "", &path_list);
180 goto_if_error(r, "Error Fapi_Delete", error);
181
182 fprintf(stderr, "\nPathList:\n%s\n", path_list);
183
184 SAFE_FREE(json_policy);
185 SAFE_FREE(signature);
186 SAFE_FREE(publicKey);
187 SAFE_FREE(policy);
188 SAFE_FREE(path_list);
189 return EXIT_SUCCESS;
190
191 error:
192 SAFE_FREE(json_policy);
193 SAFE_FREE(signature);
194 SAFE_FREE(publicKey);
195 SAFE_FREE(policy);
196 SAFE_FREE(path_list);
197 return EXIT_FAILURE;
198 }
199
200 int
201 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
202 {
203 return test_fapi_key_create_policy_pcr_sign(fapi_context);
204 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17
18
19 #include "tss2_fapi.h"
20
21 #include "test-fapi.h"
22
23 #define LOGMODULE test
24 #include "util/log.h"
25 #include "util/aux_util.h"
26
27 #define NV_SIZE 34
28 #define PASSWORD "abc"
29 #define SIGN_TEMPLATE "sign"
30
31 static TSS2_RC
32 auth_callback(
33 FAPI_CONTEXT *context,
34 char const *description,
35 char **auth,
36 void *userData)
37 {
38 (void)description;
39 (void)userData;
40 *auth = strdup(PASSWORD);
41 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
42 return TSS2_RC_SUCCESS;
43 }
44
45 static char *
46 read_policy(FAPI_CONTEXT *context, char *policy_name)
47 {
48 FILE *stream = NULL;
49 long policy_size;
50 char *json_policy = NULL;
51 char policy_file[1024];
52
53 if (snprintf(&policy_file[0], 1023, TOP_SOURCEDIR "/test/data/fapi/%s.json", policy_name) < 0)
54 return NULL;
55
56 stream = fopen(policy_file, "r");
57 if (!stream) {
58 LOG_ERROR("File %s does not exist", policy_file);
59 return NULL;
60 }
61 fseek(stream, 0L, SEEK_END);
62 policy_size = ftell(stream);
63 fclose(stream);
64 json_policy = malloc(policy_size + 1);
65 return_if_null(json_policy,
66 "Could not allocate memory for the JSON policy",
67 NULL);
68 stream = fopen(policy_file, "r");
69 ssize_t ret = read(fileno(stream), json_policy, policy_size);
70 if (ret != policy_size) {
71 LOG_ERROR("IO error %s.", policy_file);
72 return NULL;
73 }
74 json_policy[policy_size] = '\0';
75 return json_policy;
76 }
77
78 /** Test the FAPI PolicySecret and PolicyAuthValue handling.
79 *
80 * Tested FAPI commands:
81 * - Fapi_Provision()
82 * - Fapi_Import()
83 * - Fapi_CreateNv()
84 * - Fapi_CreateKey()
85 * - Fapi_Sign()
86 * - Fapi_SetAuthCB()
87 * - Fapi_Delete()
88 *
89 * Tested Policies:
90 * - PolicySecret
91 * - PolicyAuthValue
92 *
93 * @param[in,out] context The FAPI_CONTEXT.
94 * @retval EXIT_FAILURE
95 * @retval EXIT_SUCCESS
96 */
97 int
98 test_fapi_key_create_policy_secret_nv_sign(FAPI_CONTEXT *context)
99 {
100 TSS2_RC r;
101 char *nv_path_auth_object = "/nv/Owner/myNV";
102 char *policy_nv = "/policy/pol_auth_value";
103 char *policy_secret = "/policy/pol_secret";
104 char *sign_key = "/HS/SRK/mySignkey";
105 char *json_policy = NULL;
106
107 uint8_t *signature = NULL;
108 char *publicKey = NULL;
109
110 r = Fapi_Provision(context, NULL, NULL, NULL);
111 goto_if_error(r, "Error Fapi_Provision", error);
112
113 json_policy = read_policy(context, policy_nv);
114 if (!json_policy)
115 goto error;
116
117 r = Fapi_Import(context, policy_nv, json_policy);
118 goto_if_error(r, "Error Fapi_Import", error);
119
120 /* Create NV Object with policy which will be used for key authorization */
121 r = Fapi_CreateNv(context, nv_path_auth_object, "noda", 34, policy_nv, PASSWORD);
122 goto_if_error(r, "Error Fapi_CreateNv", error);
123
124 SAFE_FREE(json_policy);
125
126 json_policy = read_policy(context, policy_secret);
127 if (!json_policy)
128 goto error;
129
130 r = Fapi_Import(context, policy_secret, json_policy);
131 goto_if_error(r, "Error Fapi_Import", error);
132
133 r = Fapi_CreateKey(context, sign_key, SIGN_TEMPLATE,
134 policy_secret, "");
135 goto_if_error(r, "Error Fapi_CreateKey", error);
136
137 size_t signatureSize = 0;
138
139 TPM2B_DIGEST digest = {
140 .size = 32,
141 .buffer = {
142 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
143 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
144 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
145 0x41, 0x42
146 }
147 };
148
149 LOG_ERROR("***** START TEST ERROR ******");
150 r = Fapi_Sign(context, sign_key, NULL,
151 &digest.buffer[0], digest.size, &signature, &signatureSize,
152 &publicKey, NULL);
153
154 LOG_ERROR("***** END TEST ERROR ******");
155
156 if (r == TSS2_RC_SUCCESS)
157 goto error;
158
159 r = Fapi_SetAuthCB(context, auth_callback, "");
160 goto_if_error(r, "Error SetPolicyAuthCallback", error);
161
162 r = Fapi_Sign(context, sign_key, NULL,
163 &digest.buffer[0], digest.size, &signature, &signatureSize,
164 &publicKey, NULL);
165 goto_if_error(r, "Error Fapi_Sign", error);
166
167 r = Fapi_Delete(context, nv_path_auth_object);
168 goto_if_error(r, "Error Fapi_NV_Undefine", error);
169
170 r = Fapi_Delete(context, "/HS/SRK");
171 goto_if_error(r, "Error Fapi_Delete", error);
172
173 SAFE_FREE(signature);
174 SAFE_FREE(publicKey);
175 SAFE_FREE(json_policy);
176 return EXIT_SUCCESS;
177
178 error:
179 SAFE_FREE(signature);
180 SAFE_FREE(publicKey);
181 SAFE_FREE(json_policy);
182 return EXIT_FAILURE;
183 }
184
185 int
186 test_invoke_fapi(FAPI_CONTEXT *context)
187 {
188 return test_fapi_key_create_policy_secret_nv_sign(context);
189 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16
17 #include <openssl/evp.h>
18 #include <openssl/rsa.h>
19 #include <openssl/engine.h>
20 #include <openssl/pem.h>
21
22 #include "tss2_fapi.h"
23
24 #include "test-fapi.h"
25 #define LOGMODULE test
26 #include "util/log.h"
27 #include "util/aux_util.h"
28
29 #ifdef TEST_ECC
30 const char *priv_pem =
31 "-----BEGIN EC PRIVATE KEY-----\n"
32 "MHcCAQEEILE8jic/6w/lKoFTVblkNQ4Ls5IYibQNQ4Dk5B9R09ONoAoGCCqGSM49\n"
33 "AwEHoUQDQgAEoJTa3zftdAzHC96IjpqQ/dnLm+p7pEiLMi03Jd0oP0aYnnXFjolz\n"
34 "IB/dBZ/t+BLh0PwLM5aAM/jugeLkHgpIyQ==\n"
35 "-----END EC PRIVATE KEY-----\n";
36
37 const char *pub_pem =
38 "-----BEGIN PUBLIC KEY-----\n"
39 "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoJTa3zftdAzHC96IjpqQ/dnLm+p7\n"
40 "pEiLMi03Jd0oP0aYnnXFjolzIB/dBZ/t+BLh0PwLM5aAM/jugeLkHgpIyQ==\n"
41 "-----END PUBLIC KEY-----\n";
42 #else
43 const char *priv_pem =
44 "-----BEGIN PRIVATE KEY-----\n"
45 "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCgYvoisJIDOeYg\n"
46 "jMF6ywiZbu085TLvy5ZMhq5vfYqdgefvwpemutnfKSnpYOs5B4yO/gAD7XiYluDv\n"
47 "tqlVhfISeQV04xrWGzNImenpwm/HsgueAu8VTHNtWSL96G+BLedGTrs2NqX6cxN7\n"
48 "yGl7dQpB5X8iP4XSvpjP3Vb7gs+adwCJR6xFkt60jYFmwrAdhEzOeakhimi5rU21\n"
49 "LxCkRdEyaxS57X15L9dEA+aYJ+dvkFfZOfTqIKmTrA75F8yj161xflwtIC4hgRBg\n"
50 "K9Xb/RdN8TDrTu+20E3RjngutU4qejW9Fd3mzHJGV8HRYvjYXhUblN9wmjm7Veru\n"
51 "T2b0rnvzAgMBAAECggEBAIwHvoJ5DRJ6A50Zp3dROxHTEphfOEi6xF/OGxBGWLbK\n"
52 "C7l+eS9d5gj8BJa5QsXI/IR/6X2EYQ1AdeV04oVD7CUKuqPiALU8jFrv3pV0aGm+\n"
53 "3nu37gv3crPe5jkvLeNoM4tkA/oCXom63SDuyoG6nxkHiSdatLlaJUse4em3vRAL\n"
54 "QivziZIMyswcleMe0xAoMi7LO+nUFFxBS8/xGya0vsU0dsMQEl1SRITv1VCXmPQD\n"
55 "T4dEI4+1cufv6Ax0EDbFKmnjyiGTjOeQKrGIqETUSQolbg5PgL1XZehaaxM822OY\n"
56 "Qpnp5T0XhUEmVrOb2Wrboj+dC/2tgAN/fWXjAAxnm2ECgYEA02UTZuZ+QnD6tqo3\n"
57 "/y3n5kaM9uA2mdOIqgECI9psGF1IBIC/iP2diKyuvmQL8hzymComb5YzZl3TOAga\n"
58 "WHQYbIeU3JhnYTG75/Dv5Zh32H4NjkIJHT2/8LUM25Ove9u6QAniVgIQpBZ47LjX\n"
59 "9jHjTYCW5n79qNSfu0egYJUvypECgYEAwjqWzzEINqnX/xIVCoB4XpuDuSdkM0JW\n"
60 "MZDIH9xHjZPp07/5XYEoITylk6Zwbh+djvWDNP4gzPtuK26VsqrNxoWMsFZeXn6U\n"
61 "xSOYL2UNCZiOgchdZCOr+6r8LRUuo8xHjbawVoJVK1+tZ2WsR3ilt3Gw34O8Z5ep\n"
62 "f4v7GOXw+EMCgYAUHjFrgJIRhqkFi0uK+HZyXtJ5iDsKBqyh6Tin6tiQtQfujcYs\n"
63 "pl5ArJZwvhq47vJTcud3hSbdHh7E3ViMhHfylDChkct833vPhgl+ozT8oHpvyG8P\n"
64 "nlnO8ZwIpZR0yCOAhrBImSe2RgE6HhlHb9X/ATbbNsizMZEGBLoJlwkWUQKBgQCy\n"
65 "4U7fh2LvJUF+82JZh7RUPZn1Pmg0JVZI0/TcEv37UEy77kR1b2xMIBTGhTVq1sc/\n"
66 "ULIEbkA7SR1P9sr7//8AZSMLjJ/hG2dcoMmabNCzE8O7l5MblRbh87nIs4d+57bG\n"
67 "t4h0RBi4l6eWYLdoI59L8fNaB3PPXIiIpZ0eczeZDQKBgQC2vuFYpUZqDb9CaJsn\n"
68 "Luee6P6n5v3ZBTAT4E+GG1kWS28BiebcCuLKNAY4ZtLo08ozaTWcMxooOTeka2ux\n"
69 "fQDE4M/LTNpam8QOJ2hqECF5a0uBYNcbmaGtfA9KwIgwCZZYuwb5IDq/DRPuR690\n"
70 "i8Kp6jR2wY0suObmZHKvbCB1Dw==\n"
71 "-----END PRIVATE KEY-----\n";
72
73 const char *pub_pem =
74 "-----BEGIN PUBLIC KEY-----\n"
75 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoGL6IrCSAznmIIzBessI\n"
76 "mW7tPOUy78uWTIaub32KnYHn78KXprrZ3ykp6WDrOQeMjv4AA+14mJbg77apVYXy\n"
77 "EnkFdOMa1hszSJnp6cJvx7ILngLvFUxzbVki/ehvgS3nRk67Njal+nMTe8hpe3UK\n"
78 "QeV/Ij+F0r6Yz91W+4LPmncAiUesRZLetI2BZsKwHYRMznmpIYpoua1NtS8QpEXR\n"
79 "MmsUue19eS/XRAPmmCfnb5BX2Tn06iCpk6wO+RfMo9etcX5cLSAuIYEQYCvV2/0X\n"
80 "TfEw607vttBN0Y54LrVOKno1vRXd5sxyRlfB0WL42F4VG5TfcJo5u1Xq7k9m9K57\n"
81 "8wIDAQAB\n"
82 "-----END PUBLIC KEY-----\n";
83 #endif /* TEST_ECC */
84
85 #define RSA_SIG_SCHEME RSA_PKCS1_PSS_PADDING
86
87 char *userDataTest = "test";
88
89 #define chknull(X) if (!X) { LOG_ERROR(str(X) "should not be null"); \
90 r = TSS2_FAPI_RC_GENERAL_FAILURE; \
91 goto error_cleanup; }
92
93 static TSS2_RC
94 signatureCallback(
95 FAPI_CONTEXT *context,
96 char const *description,
97 char const *publicKey,
98 char const *publicKeyHint,
99 uint32_t hashAlg,
100 uint8_t const *dataToSign,
101 size_t dataToSignSize,
102 uint8_t **signature,
103 size_t *signatureSize,
104 void *userData)
105 {
106 (void)description;
107 (void)publicKey;
108 (void)publicKeyHint;
109
110 if (userData != userDataTest) {
111 LOG_ERROR("userData is not correct, %p != %p", userData, userDataTest);
112 return TSS2_FAPI_RC_GENERAL_FAILURE;
113 }
114
115 if (hashAlg != TPM2_ALG_SHA1) {
116 LOG_ERROR("hashAlg is not correct, %u != %u", hashAlg, TPM2_ALG_SHA256);
117 return TSS2_FAPI_RC_GENERAL_FAILURE;
118 }
119
120 TSS2_RC r = TSS2_RC_SUCCESS;
121 EVP_PKEY *priv_key = NULL;
122 BIO *bufio = NULL;
123 EVP_MD_CTX *mdctx = NULL;
124 EVP_PKEY_CTX *pctx = NULL;
125
126 const EVP_MD *ossl_hash = EVP_sha1();
127 chknull(ossl_hash);
128
129 LOGBLOB_DEBUG(dataToSign, dataToSignSize, "Data to be signed");
130
131 bufio = BIO_new_mem_buf((void *)priv_pem, strlen(priv_pem));
132 priv_key = PEM_read_bio_PrivateKey(bufio, NULL, NULL, NULL);
133 chknull(priv_key);
134
135 mdctx = EVP_MD_CTX_create();
136 chknull(mdctx);
137
138 if (1 != EVP_DigestSignInit(mdctx, &pctx, NULL, NULL, priv_key)) {
139 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL digest sign init.",
140 error_cleanup);
141 }
142 if (EVP_PKEY_type(EVP_PKEY_id(priv_key)) == EVP_PKEY_RSA) {
143 int signing_scheme = RSA_SIG_SCHEME;
144 if (1 != EVP_PKEY_CTX_set_rsa_padding(pctx, signing_scheme)) {
145 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL set RSA padding.",
146 error_cleanup);
147 }
148 }
149 if (1 != EVP_DigestSignInit(mdctx, &pctx, ossl_hash, NULL, priv_key)) {
150 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign init.",
151 error_cleanup);
152 }
153 if (1 != EVP_DigestSignUpdate(mdctx, dataToSign, dataToSignSize)) {
154 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign update.",
155 error_cleanup);
156 }
157 if (1 != EVP_DigestSignFinal(mdctx, NULL, signatureSize)) {
158 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign final.",
159 error_cleanup);
160 }
161 *signature = malloc(*signatureSize);
162 chknull(*signature);
163 if (1 != EVP_DigestSignFinal(mdctx, *signature, signatureSize)) {
164 goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "OSSL sign final.",
165 error_cleanup);
166 }
167 error_cleanup:
168 if (priv_key)
169 EVP_PKEY_free(priv_key);
170 if (bufio)
171 BIO_free(bufio);
172 if (mdctx)
173 EVP_MD_CTX_destroy(mdctx);
174 return r;
175 }
176
177 #define PASSWORD NULL
178
179 #define SIGN_TEMPLATE "sign,noDa"
180
181 /** Test the FAPI functions for key creation and usage with a PolicySigned.
182 *
183 * Tested FAPI commands:
184 * - Fapi_Provision()
185 * - Fapi_Import()
186 * - Fapi_CreateKey()
187 * - Fapi_SetSignCB()
188 * - Fapi_Sign()
189 * - Fapi_Delete()
190 * - Fapi_List()
191 *
192 * Tested Policies:
193 * - PolicySigned
194 *
195 * @param[in,out] context The FAPI_CONTEXT.
196 * @retval EXIT_FAILURE
197 * @retval EXIT_SUCCESS
198 */
199 int
200 test_fapi_key_create_policy_signed(FAPI_CONTEXT *context)
201 {
202 TSS2_RC r;
203 #ifdef TEST_ECC
204 char *policy_name = "/policy/pol_signed_ecc";
205 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_signed_ecc.json";
206 #else
207 char *policy_name = "/policy/pol_signed";
208 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_signed.json";
209 #endif
210 FILE *stream = NULL;
211 char *json_policy = NULL;
212 long policy_size;
213
214 uint8_t *signature = NULL;
215 char *publicKey = NULL;
216 char *pathList = NULL;
217
218 r = Fapi_Provision(context, NULL, NULL, NULL);
219 goto_if_error(r, "Error Fapi_Provision", error);
220
221 r = pcr_reset(context, 16);
222 goto_if_error(r, "Error pcr_reset", error);
223
224 stream = fopen(policy_file, "r");
225 if (!stream) {
226 LOG_ERROR("File %s does not exist", policy_file);
227 goto error;
228 }
229 fseek(stream, 0L, SEEK_END);
230 policy_size = ftell(stream);
231 fclose(stream);
232 json_policy = malloc(policy_size + 1);
233 goto_if_null(json_policy,
234 "Could not allocate memory for the JSON policy",
235 TSS2_FAPI_RC_MEMORY, error);
236 stream = fopen(policy_file, "r");
237 ssize_t ret = read(fileno(stream), json_policy, policy_size);
238 if (ret != policy_size) {
239 LOG_ERROR("IO error %s.", policy_file);
240 goto error;
241 }
242 json_policy[policy_size] = '\0';
243
244 r = Fapi_Import(context, policy_name, json_policy);
245 goto_if_error(r, "Error Fapi_Import", error);
246
247 r = Fapi_CreateKey(context, "/HS/SRK/mySignKey", SIGN_TEMPLATE,
248 policy_name, PASSWORD);
249 goto_if_error(r, "Error Fapi_CreateKey", error);
250 size_t signatureSize = 0;
251
252 TPM2B_DIGEST digest = {
253 .size = 20,
254 .buffer = {
255 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
256 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
257 }
258 };
259
260 r = Fapi_SetSignCB(context, signatureCallback, userDataTest);
261 goto_if_error(r, "Error SetPolicySignatureCallback", error);
262
263 r = Fapi_Sign(context, "/HS/SRK/mySignKey", NULL,
264 &digest.buffer[0], digest.size, &signature, &signatureSize,
265 &publicKey, NULL);
266 goto_if_error(r, "Error Fapi_Sign", error);
267
268 r = Fapi_Delete(context, "/HS/SRK");
269 goto_if_error(r, "Error Fapi_Delete", error);
270
271 r = Fapi_List(context, "/", &pathList);
272 goto_if_error(r, "Error Fapi_List", error);
273
274 fprintf(stderr, "\n%s\n", pathList);
275
276 fclose(stream);
277 SAFE_FREE(json_policy);
278 SAFE_FREE(signature);
279 SAFE_FREE(publicKey);
280 SAFE_FREE(pathList);
281 return EXIT_SUCCESS;
282
283 error:
284 SAFE_FREE(json_policy);
285 SAFE_FREE(signature);
286 SAFE_FREE(publicKey);
287 SAFE_FREE(pathList);
288 return EXIT_FAILURE;
289 }
290
291 int
292 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
293 {
294 return test_fapi_key_create_policy_signed(fapi_context);
295 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11
12 #include "tss2_fapi.h"
13
14 #include "test-fapi.h"
15 #include "fapi_util.h"
16 #include "fapi_int.h"
17
18 #include "esys_iutil.h"
19 #define LOGMODULE test
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 #define PASSWORD "abc"
24 #define SIGN_TEMPLATE "sign,noDa"
25
26 static TSS2_RC
27 auth_callback(
28 FAPI_CONTEXT *context,
29 char const *description,
30 char **auth,
31 void *userData)
32 {
33 (void)description;
34 (void)userData;
35 char *pw = PASSWORD;
36 if (!pw)
37 return TSS2_FAPI_RC_GENERAL_FAILURE;
38
39 *auth = strdup(pw);
40 return TSS2_RC_SUCCESS;
41 }
42
43 /** Test the FAPI functions for key creation and usage with an SH password.
44 *
45 * Tested FAPI commands:
46 * - Fapi_Provision()
47 * - Fapi_SetAuthCB()
48 * - Fapi_CreateKey()
49 * - Fapi_GetTpmBlobs()
50 * - Fapi_Sign()
51 * - Fapi_SetCertificate()
52 * - Fapi_List()
53 * - Fapi_ChangeAuth()
54 * - Fapi_Delete()
55 *
56 * @param[in,out] context The FAPI_CONTEXT.
57 * @retval EXIT_FAILURE
58 * @retval EXIT_SUCCESS
59 */
60 int
61 test_fapi_key_create_sign_password_provision(FAPI_CONTEXT *context)
62 {
63 TSS2_RC r;
64 char *sigscheme = NULL;
65 uint8_t *publicblob = NULL;
66 uint8_t *privateblob = NULL;
67 uint8_t *signature = NULL;
68 char *publicKey = NULL;
69 char *path_list = NULL;
70
71 size_t publicsize;
72 size_t privatesize;
73
74 const char *cert =
75 "-----BEGIN CERTIFICATE-----\n"
76 "MIIDBjCCAe4CCQDcvXBOEVM0UTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE\n"
77 "RTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0\n"
78 "cyBQdHkgTHRkMB4XDTE5MDIyODEwNDkyM1oXDTM1MDgyNzEwNDkyM1owRTELMAkG\n"
79 "A1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0\n"
80 "IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
81 "AKBi+iKwkgM55iCMwXrLCJlu7TzlMu/LlkyGrm99ip2B5+/Cl6a62d8pKelg6zkH\n"
82 "jI7+AAPteJiW4O+2qVWF8hJ5BXTjGtYbM0iZ6enCb8eyC54C7xVMc21ZIv3ob4Et\n"
83 "50ZOuzY2pfpzE3vIaXt1CkHlfyI/hdK+mM/dVvuCz5p3AIlHrEWS3rSNgWbCsB2E\n"
84 "TM55qSGKaLmtTbUvEKRF0TJrFLntfXkv10QD5pgn52+QV9k59OogqZOsDvkXzKPX\n"
85 "rXF+XC0gLiGBEGAr1dv9F03xMOtO77bQTdGOeC61Tip6Nb0V3ebMckZXwdFi+Nhe\n"
86 "FRuU33CaObtV6u5PZvSue/MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAcamUPe8I\n"
87 "nMOHcv9x5lVN1joihVRmKc0QqNLFc6XpJY8+U5rGkZvOcDe9Da8L97wDNXpKmU/q\n"
88 "pprj3rT8l3v0Z5xs8Vdr8lxS6T5NhqQV0UCsn1x14gZJcE48y9/LazYi6Zcar+BX\n"
89 "Am4vewAV3HmQ8X2EctsRhXe4wlAq4slIfEWaaofa8ai7BzO9KwpMLsGPWoNetkB9\n"
90 "19+SFt0lFFOj/6vDw5pCpSd1nQlo1ug69mJYSX/wcGkV4t4LfGhV8jRPDsGs6I5n\n"
91 "ETHSN5KV1XCPYJmRCjFY7sIt1x4zN7JJRO9DVw+YheIlduVfkBiF+GlQgLlFTjrJ\n"
92 "VrpSGMIFSu301A==\n"
93 "-----END CERTIFICATE-----\n";
94
95 if (strcmp("P_ECC", fapi_profile) != 0)
96 sigscheme = "RSA_PSS";
97
98 /* We need to reset the passwords again, in order to not brick physical TPMs */
99 r = Fapi_Provision(context, NULL, PASSWORD, NULL);
100 goto_if_error(r, "Error Fapi_Provision", error);
101
102 r = Fapi_SetAuthCB(context, auth_callback, NULL);
103 goto_if_error(r, "Error SetPolicyAuthCallback", error);
104
105 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", SIGN_TEMPLATE, "",
106 PASSWORD);
107
108 goto_if_error(r, "Error Fapi_CreateKey", error);
109 size_t signatureSize = 0;
110
111 TPM2B_DIGEST digest = {
112 .size = 20,
113 .buffer = {
114 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
115 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
116 }
117 };
118
119 r = Fapi_GetTpmBlobs(context, "HS/SRK/mySignKey", &publicblob,
120 &publicsize,
121 &privateblob, &privatesize, NULL);
122 goto_if_error(r, "Error Fapi_GetTpmBlobs", error);
123
124 r = Fapi_Sign(context, "HS/SRK/mySignKey", sigscheme,
125 &digest.buffer[0], digest.size, &signature, &signatureSize,
126 &publicKey, NULL);
127 goto_if_error(r, "Error Fapi_Sign", error);
128
129 r = Fapi_SetCertificate(context, "HS/SRK/mySignKey", cert);
130 goto_if_error(r, "Error Fapi_SetCertificate", error);
131
132 r = Fapi_List(context, "/", &path_list);
133 goto_if_error(r, "Error Fapi_Delete", error);
134
135 fprintf(stderr, "\nPathList:\n%s\n", path_list);
136
137 /* We need to reset the passwords again, in order to not brick physical TPMs */
138 r = Fapi_ChangeAuth(context, "/HS", NULL);
139 goto_if_error(r, "Error Fapi_ChangeAuth", error);
140
141 r = Fapi_Delete(context, "/");
142 goto_if_error(r, "Error Fapi_Delete", error);
143
144 SAFE_FREE(publicblob);
145 SAFE_FREE(privateblob);
146 SAFE_FREE(signature);
147 SAFE_FREE(publicKey);
148 SAFE_FREE(path_list);
149 return EXIT_SUCCESS;
150
151 error:
152 Fapi_Delete(context, "/HS/SRK");
153 SAFE_FREE(publicblob);
154 SAFE_FREE(privateblob);
155 SAFE_FREE(signature);
156 SAFE_FREE(publicKey);
157 SAFE_FREE(path_list);
158 return EXIT_FAILURE;
159 }
160
161 int
162 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
163 {
164 return test_fapi_key_create_sign_password_provision(fapi_context);
165 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14
15 #include "test-fapi.h"
16 #define LOGMODULE test
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20 #define PASSWORD NULL
21 #define SIGN_TEMPLATE "sign,noDa"
22
23 static TSS2_RC
24 auth_callback(
25 FAPI_CONTEXT *context,
26 char const *description,
27 char **auth,
28 void *userData)
29 {
30 (void)description;
31 (void)userData;
32 char *pw = PASSWORD;
33 if (!pw)
34 return TSS2_FAPI_RC_GENERAL_FAILURE;
35
36 *auth = strdup(pw);
37 return TSS2_RC_SUCCESS;
38 }
39
40 /** Test the FAPI functions for key creation and usage.
41 *
42 * Tested FAPI commands:
43 * - Fapi_Provision()
44 * - Fapi_SetAuthCB()
45 * - Fapi_CreateKey()
46 * - Fapi_GetTpmBlobs()
47 * - Fapi_Sign()
48 * - Fapi_SetCertificate()
49 * - Fapi_List()
50 * - Fapi_Delete()
51 *
52 * @param[in,out] context The FAPI_CONTEXT.
53 * @retval EXIT_FAILURE
54 * @retval EXIT_SUCCESS
55 */
56 int
57 test_fapi_key_create_sign_policy_provision(FAPI_CONTEXT *context)
58 {
59 TSS2_RC r;
60 char *sigscheme = NULL;
61 uint8_t *publicblob = NULL;
62 uint8_t *privateblob = NULL;
63 uint8_t *signature = NULL;
64 char *publicKey = NULL;
65 char *path_list = NULL;
66
67 const char *cert =
68 "-----BEGIN CERTIFICATE-----\n"
69 "MIIDBjCCAe4CCQDcvXBOEVM0UTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE\n"
70 "RTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0\n"
71 "cyBQdHkgTHRkMB4XDTE5MDIyODEwNDkyM1oXDTM1MDgyNzEwNDkyM1owRTELMAkG\n"
72 "A1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0\n"
73 "IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
74 "AKBi+iKwkgM55iCMwXrLCJlu7TzlMu/LlkyGrm99ip2B5+/Cl6a62d8pKelg6zkH\n"
75 "jI7+AAPteJiW4O+2qVWF8hJ5BXTjGtYbM0iZ6enCb8eyC54C7xVMc21ZIv3ob4Et\n"
76 "50ZOuzY2pfpzE3vIaXt1CkHlfyI/hdK+mM/dVvuCz5p3AIlHrEWS3rSNgWbCsB2E\n"
77 "TM55qSGKaLmtTbUvEKRF0TJrFLntfXkv10QD5pgn52+QV9k59OogqZOsDvkXzKPX\n"
78 "rXF+XC0gLiGBEGAr1dv9F03xMOtO77bQTdGOeC61Tip6Nb0V3ebMckZXwdFi+Nhe\n"
79 "FRuU33CaObtV6u5PZvSue/MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAcamUPe8I\n"
80 "nMOHcv9x5lVN1joihVRmKc0QqNLFc6XpJY8+U5rGkZvOcDe9Da8L97wDNXpKmU/q\n"
81 "pprj3rT8l3v0Z5xs8Vdr8lxS6T5NhqQV0UCsn1x14gZJcE48y9/LazYi6Zcar+BX\n"
82 "Am4vewAV3HmQ8X2EctsRhXe4wlAq4slIfEWaaofa8ai7BzO9KwpMLsGPWoNetkB9\n"
83 "19+SFt0lFFOj/6vDw5pCpSd1nQlo1ug69mJYSX/wcGkV4t4LfGhV8jRPDsGs6I5n\n"
84 "ETHSN5KV1XCPYJmRCjFY7sIt1x4zN7JJRO9DVw+YheIlduVfkBiF+GlQgLlFTjrJ\n"
85 "VrpSGMIFSu301A==\n"
86 "-----END CERTIFICATE-----\n";
87
88 if (strcmp("P_ECC", fapi_profile) != 0)
89 sigscheme = "RSA_PSS";
90
91 /* We need to reset the passwords again, in order to not brick physical TPMs */
92 r = Fapi_Provision(context, NULL, PASSWORD, NULL);
93 goto_if_error(r, "Error Fapi_Provision", error);
94
95 r = Fapi_SetAuthCB(context, auth_callback, NULL);
96 goto_if_error(r, "Error SetPolicyAuthCallback", error);
97
98 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", SIGN_TEMPLATE, "",
99 PASSWORD);
100
101 goto_if_error(r, "Error Fapi_CreateKey", error);
102 size_t signatureSize = 0;
103
104 TPM2B_DIGEST digest = {
105 .size = 20,
106 .buffer = {
107 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
108 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
109 }
110 };
111
112 size_t publicsize;
113 size_t privatesize;
114
115 r = Fapi_GetTpmBlobs(context, "HS/SRK/mySignKey", &publicblob,
116 &publicsize,
117 &privateblob, &privatesize, NULL);
118 goto_if_error(r, "Error Fapi_GetTpmBlobs", error);
119
120 r = Fapi_Sign(context, "HS/SRK/mySignKey", sigscheme,
121 &digest.buffer[0], digest.size, &signature, &signatureSize,
122 &publicKey, NULL);
123 goto_if_error(r, "Error Fapi_Sign", error);
124
125
126 r = Fapi_SetCertificate(context, "HS/SRK/mySignKey", cert);
127 goto_if_error(r, "Error Fapi_SetCertificate", error);
128
129 r = Fapi_List(context, "/", &path_list);
130 goto_if_error(r, "Error Fapi_Delete", error);
131
132 LOG_INFO("\nPathList:\n%s\n", path_list);
133
134 r = Fapi_Delete(context, "/");
135 goto_if_error(r, "Error Fapi_Delete", error);
136
137 SAFE_FREE(publicblob);
138 SAFE_FREE(privateblob);
139 SAFE_FREE(signature);
140 SAFE_FREE(publicKey);
141 SAFE_FREE(path_list);
142 return EXIT_SUCCESS;
143
144 error:
145 Fapi_Delete(context, "/HS/SRK");
146 SAFE_FREE(publicblob);
147 SAFE_FREE(privateblob);
148 SAFE_FREE(signature);
149 SAFE_FREE(publicKey);
150 SAFE_FREE(path_list);
151 return EXIT_FAILURE;
152 }
153
154 int
155 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
156 {
157 return test_fapi_key_create_sign_policy_provision(fapi_context);
158 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11
12 #include "tss2_fapi.h"
13
14 #include "test-fapi.h"
15 #include "fapi_util.h"
16 #include "fapi_int.h"
17
18 #include "esys_iutil.h"
19 #define LOGMODULE test
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 #define PASSWORD "abc"
24 #define SIGN_TEMPLATE "sign,noDa"
25
26
27 static TSS2_RC
28 auth_callback(
29 FAPI_CONTEXT *context,
30 char const *description,
31 char **auth,
32 void *userData)
33 {
34 (void)description;
35 (void)userData;
36 *auth = strdup(PASSWORD);
37 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
38 return TSS2_RC_SUCCESS;
39 }
40
41 /** Test the FAPI functions for TpmBlobs and certificates.
42 *
43 * Tested FAPI commands:
44 * - Fapi_Provision()
45 * - Fapi_SetAuthCB()
46 * - Fapi_CreateKey()
47 * - Fapi_GetTpmBlobs()
48 * - Fapi_Sign()
49 * - Fapi_VerifySignature()
50 * - Fapi_SetCertificate()
51 * - Fapi_List()
52 * - Fapi_ChangeAuth()
53 * - Fapi_Delete()
54 *
55 * @param[in,out] context The FAPI_CONTEXT.
56 * @retval EXIT_FAILURE
57 * @retval EXIT_SUCCESS
58 */
59 int
60 test_fapi_key_create_sign(FAPI_CONTEXT *context)
61 {
62 TSS2_RC r;
63 char *sigscheme = NULL;
64
65 const char *cert =
66 "-----BEGIN CERTIFICATE-----\n"
67 "MIIDBjCCAe4CCQDcvXBOEVM0UTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE\n"
68 "RTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0\n"
69 "cyBQdHkgTHRkMB4XDTE5MDIyODEwNDkyM1oXDTM1MDgyNzEwNDkyM1owRTELMAkG\n"
70 "A1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0\n"
71 "IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
72 "AKBi+iKwkgM55iCMwXrLCJlu7TzlMu/LlkyGrm99ip2B5+/Cl6a62d8pKelg6zkH\n"
73 "jI7+AAPteJiW4O+2qVWF8hJ5BXTjGtYbM0iZ6enCb8eyC54C7xVMc21ZIv3ob4Et\n"
74 "50ZOuzY2pfpzE3vIaXt1CkHlfyI/hdK+mM/dVvuCz5p3AIlHrEWS3rSNgWbCsB2E\n"
75 "TM55qSGKaLmtTbUvEKRF0TJrFLntfXkv10QD5pgn52+QV9k59OogqZOsDvkXzKPX\n"
76 "rXF+XC0gLiGBEGAr1dv9F03xMOtO77bQTdGOeC61Tip6Nb0V3ebMckZXwdFi+Nhe\n"
77 "FRuU33CaObtV6u5PZvSue/MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAcamUPe8I\n"
78 "nMOHcv9x5lVN1joihVRmKc0QqNLFc6XpJY8+U5rGkZvOcDe9Da8L97wDNXpKmU/q\n"
79 "pprj3rT8l3v0Z5xs8Vdr8lxS6T5NhqQV0UCsn1x14gZJcE48y9/LazYi6Zcar+BX\n"
80 "Am4vewAV3HmQ8X2EctsRhXe4wlAq4slIfEWaaofa8ai7BzO9KwpMLsGPWoNetkB9\n"
81 "19+SFt0lFFOj/6vDw5pCpSd1nQlo1ug69mJYSX/wcGkV4t4LfGhV8jRPDsGs6I5n\n"
82 "ETHSN5KV1XCPYJmRCjFY7sIt1x4zN7JJRO9DVw+YheIlduVfkBiF+GlQgLlFTjrJ\n"
83 "VrpSGMIFSu301A==\n"
84 "-----END CERTIFICATE-----\n";
85
86 uint8_t *signature = NULL;
87 char *publicKey = NULL;
88 uint8_t *publicblob = NULL;
89 uint8_t *privateblob = NULL;
90 char *path_list = NULL;
91 size_t publicsize;
92 size_t privatesize;
93
94 if (strcmp("P_ECC", fapi_profile) != 0)
95 sigscheme = "RSA_PSS";
96
97 /* We need to reset the passwords again, in order to not brick physical TPMs */
98 r = Fapi_Provision(context, NULL, PASSWORD, NULL);
99 goto_if_error(r, "Error Fapi_Provision", error);
100
101 r = Fapi_SetAuthCB(context, auth_callback, NULL);
102 goto_if_error(r, "Error SetPolicyAuthCallback", error);
103
104 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", SIGN_TEMPLATE, "",
105 PASSWORD);
106 goto_if_error(r, "Error Fapi_CreateKey_Async", error);
107
108 goto_if_error(r, "Error Fapi_CreateKey_Finish", error);
109 size_t signatureSize = 0;
110
111 TPM2B_DIGEST digest = {
112 .size = 32,
113 .buffer = {
114 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
115 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
116 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
117 0x67, 0x68
118 }
119 };
120
121 r = Fapi_GetTpmBlobs(context, "HS/SRK/mySignKey", &publicblob,
122 &publicsize,
123 &privateblob, &privatesize, NULL);
124 goto_if_error(r, "Error Fapi_GetTpmBlobs", error);
125
126 r = Fapi_Sign(context, "HS/SRK/mySignKey", sigscheme,
127 &digest.buffer[0], digest.size, &signature, &signatureSize,
128 &publicKey, NULL);
129 goto_if_error(r, "Error Fapi_Sign", error);
130
131 r = Fapi_VerifySignature(context, "HS/SRK/mySignKey",
132 &digest.buffer[0], digest.size, signature, signatureSize);
133 goto_if_error(r, "Error Fapi_VerifySignature", error);
134
135
136 r = Fapi_SetCertificate(context, "HS/SRK/mySignKey", cert);
137 goto_if_error(r, "Error Fapi_SetCertificate", error);
138
139 r = Fapi_List(context, "/", &path_list);
140 goto_if_error(r, "Error Fapi_Delete", error);
141
142 fprintf(stderr, "\nPathList:\n%s\n", path_list);
143
144 /* We need to reset the passwords again, in order to not brick physical TPMs */
145 r = Fapi_ChangeAuth(context, "/HS", NULL);
146 goto_if_error(r, "Error Fapi_ChangeAuth", error);
147
148 r = Fapi_Delete(context, "/");
149 goto_if_error(r, "Error Fapi_Delete", error);
150
151 SAFE_FREE(path_list);
152 SAFE_FREE(publicblob);
153 SAFE_FREE(privateblob);
154 SAFE_FREE(publicKey);
155 SAFE_FREE(signature);
156 return EXIT_SUCCESS;
157
158 error:
159 Fapi_Delete(context, "/HS/SRK");
160 SAFE_FREE(path_list);
161 SAFE_FREE(publicblob);
162 SAFE_FREE(privateblob);
163 SAFE_FREE(publicKey);
164 SAFE_FREE(signature);
165 return EXIT_FAILURE;
166 }
167
168 int
169 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
170 {
171 return test_fapi_key_create_sign(fapi_context);
172 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14 #include <unistd.h>
15
16 #include "tss2_fapi.h"
17 #include "tss2_esys.h"
18
19 #include "test-fapi.h"
20 #define LOGMODULE test
21 #include "util/log.h"
22 #include "util/aux_util.h"
23
24 static TSS2_RC
25 check_tpm_cmd(FAPI_CONTEXT *context, TPM2_CC command_code)
26 {
27 TSS2_RC r;
28 TSS2_TCTI_CONTEXT *tcti;
29 ESYS_CONTEXT *esys;
30 TPMS_CAPABILITY_DATA *cap_data;
31
32 r = Fapi_GetTcti(context, &tcti);
33 goto_if_error(r, "Error Fapi_GetTcti", error);
34
35 r = Esys_Initialize(&esys, tcti, NULL);
36 goto_if_error(r, "Error Fapi_GetTcti", error);
37
38 r = Esys_GetCapability(esys,
39 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
40 TPM2_CAP_COMMANDS, command_code, 1, NULL, &cap_data);
41 Esys_Finalize(&esys);
42 return_if_error(r, "Error: GetCapabilities");
43
44 if ((cap_data->data.command.commandAttributes[0] & TPMA_CC_COMMANDINDEX_MASK) ==
45 command_code) {
46 free(cap_data);
47 return TSS2_RC_SUCCESS;
48 } else {
49 free(cap_data);
50 return TSS2_FAPI_RC_NOT_IMPLEMENTED;
51 }
52
53 error:
54 return r;
55 }
56
57 /** Test the FAPI PolicyCpHash but means of AuthorizeNv.
58 *
59 * Tested FAPI commands:
60 * - Fapi_GetTcti()
61 * - Fapi_Provision()
62 * - Fapi_Import()
63 * - Fapi_CreateNv()
64 * - Fapi_WriteAuthorizeNv
65 * - Fapi_NvWrite()
66 *
67 * Tested Policies:
68 * - PolicyAuthorize
69 * - PolicyCpHash
70 *
71 * @param[in,out] context The FAPI_CONTEXT.
72 * @retval EXIT_FAILURE
73 * @retval EXIT_SUCCESS
74 */
75 int
76 test_fapi_nv_authorizenv_cphash(FAPI_CONTEXT *context)
77 {
78 TSS2_RC r;
79 ssize_t ret;
80 uint8_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
81 char *policy1_name = "/policy/pol_authorize_nv";
82 char *policy1_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_authorize_nv.json";
83 char *policy2_name = "/policy/pol_cphash";
84 char *policy2_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_cphash.json";
85 FILE *stream = NULL;
86 char json[1024];
87
88 if (check_tpm_cmd(context, TPM2_CC_PolicyAuthorizeNV) != TPM2_RC_SUCCESS) {
89 LOG_WARNING("Command PolicyAuthorizeNV not available.");
90 return EXIT_SKIP;
91 }
92
93 r = Fapi_Provision(context, NULL, NULL, NULL);
94 goto_if_error(r, "Error Fapi_Provision", error);
95
96 memset(&json[0], 0, sizeof(json));
97 stream = fopen(policy1_file, "r");
98 ret = read(fileno(stream), &json[0], sizeof(json));
99 fclose(stream);
100 if (ret < 0) {
101 LOG_ERROR("IO error %s.", policy1_file);
102 goto error;
103 }
104 json[ret] = '\0';
105 r = Fapi_Import(context, policy1_name, json);
106 goto_if_error(r, "Error Fapi_Import", error);
107
108 memset(&json[0], 0, sizeof(json));
109 stream = fopen(policy2_file, "r");
110 ret = read(fileno(stream), &json[0], sizeof(json));
111 fclose(stream);
112 if (ret < 0) {
113 LOG_ERROR("IO error %s.", policy2_file);
114 goto error;
115 }
116 json[ret] = '\0';
117 r = Fapi_Import(context, policy2_name, json);
118 goto_if_error(r, "Error Fapi_Import", error);
119
120 /* Start the test */
121
122 r = Fapi_CreateNv(context, "/nv/Owner/myNV", "", 34, "", "");
123 goto_if_error(r, "Error Fapi_CreateNv", error);
124
125
126 r = Fapi_CreateNv(context, "/nv/Owner/myNV2", "", sizeof(data), policy1_name, "");
127 goto_if_error(r, "Error Fapi_CreateNv", error);
128
129 r = Fapi_WriteAuthorizeNv(context, "/nv/Owner/myNV", policy2_name);
130 goto_if_error(r, "Error Fapi_WriteAuthorizeNv", error);
131
132 r = Fapi_NvWrite(context, "/nv/Owner/myNV2", &data[0], sizeof(data));
133 goto_if_error(r, "Error Fapi_NvWrite", error);
134
135 /* Cleanup */
136
137 r = Fapi_Delete(context, "/nv/Owner/myNV");
138 goto_if_error(r, "Error Fapi_NV_Undefine", error);
139
140 r = Fapi_Delete(context, "/nv/Owner/myNV2");
141 goto_if_error(r, "Error Fapi_NV_Undefine", error);
142
143 r = Fapi_Delete(context, "/");
144 goto_if_error(r, "Error Fapi_Delete", error);
145
146 return EXIT_SUCCESS;
147
148 error:
149 return EXIT_FAILURE;
150 }
151
152 int
153 test_invoke_fapi(FAPI_CONTEXT *context)
154 {
155 return test_fapi_nv_authorizenv_cphash(context);
156 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14
15 #include "tss2_fapi.h"
16
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 #define NV_SIZE 32
22
23 #define PASSWORD "abc"
24
25 static char *password;
26
27 static TSS2_RC
28 auth_callback(
29 FAPI_CONTEXT *context,
30 char const *description,
31 char **auth,
32 void *userData)
33 {
34 (void)description;
35 (void)userData;
36 *auth = strdup(password);
37 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
38 return TSS2_RC_SUCCESS;
39 }
40
41
42 /** Test the FAPI function FAPI_NvExtend.
43 *
44 * Tested FAPI commands:
45 * - Fapi_Provision()
46 * - Fapi_CreateNv()
47 * - Fapi_NvExtend()
48 * - Fapi_Delete()
49 * - Fapi_SetAuthCB()
50 *
51 * @param[in,out] context The FAPI_CONTEXT.
52 * @retval EXIT_FAILURE
53 * @retval EXIT_SUCCESS
54 */
55 int
56 test_fapi_nv_extend(FAPI_CONTEXT *context)
57 {
58 TSS2_RC r;
59 char *nvPathExtend = "/nv/Owner/myNVextend";
60 uint8_t *data_dest = NULL;
61 char *log = NULL;
62 size_t dest_size;
63
64 r = Fapi_Provision(context, NULL, NULL, NULL);
65 goto_if_error(r, "Error Fapi_Provision", error);
66
67 /* Test no password, noda set */
68 r = Fapi_CreateNv(context, nvPathExtend, "pcr, noda", 0, "", "");
69 goto_if_error(r, "Error Fapi_CreateNv", error);
70
71 uint8_t data_src[NV_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
72 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
73 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
74 0, 1
75 };
76
77
78 r = Fapi_NvExtend(context, nvPathExtend, &data_src[0], NV_SIZE, "{ \"test\": \"myfile\" }");
79 goto_if_error(r, "Error Fapi_NV_EXTEND", error);
80
81 r = Fapi_NvRead(context, nvPathExtend, &data_dest, &dest_size, &log);
82 goto_if_error(r, "Error Fapi_NvRead", error);
83
84 fprintf(stderr, "\nLog:\n%s\n", log);
85 SAFE_FREE(data_dest);
86
87 r = Fapi_NvExtend(context, nvPathExtend, &data_src[0], NV_SIZE, "{ \"test\": \"myfile\" }");
88 goto_if_error(r, "Error Fapi_NV_EXTEND", error);
89
90 SAFE_FREE(log);
91 r = Fapi_NvRead(context, nvPathExtend, &data_dest, &dest_size, &log);
92 goto_if_error(r, "Error Fapi_NvRead", error);
93
94 fprintf(stderr, "\nLog:\n%s\n", log);
95
96 r = Fapi_Delete(context, nvPathExtend);
97 goto_if_error(r, "Error Fapi_NV_Undefine", error);
98
99 r = Fapi_SetAuthCB(context, auth_callback, "");
100 goto_if_error(r, "Error SetPolicyAuthCallback", error);
101
102 /* Test with password noda set */
103 password = PASSWORD;
104 r = Fapi_CreateNv(context, nvPathExtend, "pcr, noda", 0, "", PASSWORD);
105 goto_if_error(r, "Error Fapi_CreateNv", error);
106
107 r = Fapi_SetAuthCB(context, auth_callback, "");
108 goto_if_error(r, "Error SetPolicyAuthCallback", error);
109
110 r = Fapi_NvExtend(context, nvPathExtend, &data_src[0], NV_SIZE, "{ \"test\": \"myfile\" }");
111 goto_if_error(r, "Error Fapi_NV_EXTEN", error);
112
113 r = Fapi_Delete(context, nvPathExtend);
114 goto_if_error(r, "Error Fapi_NV_Undefine", error);
115
116 /* Test no password, noda clear */
117 password = "";
118 r = Fapi_CreateNv(context, nvPathExtend, "pcr", 0, "", "");
119 goto_if_error(r, "Error Fapi_CreateNv", error);
120
121 r = Fapi_NvExtend(context, nvPathExtend, &data_src[0], NV_SIZE, "{ \"test\": \"myfile\" }");
122 goto_if_error(r, "Error Fapi_NV_EXTEN", error);
123
124 r = Fapi_Delete(context, nvPathExtend);
125 goto_if_error(r, "Error Fapi_NV_Undefine", error);
126
127 /* Test with password noda clear */
128 password = PASSWORD;
129 r = Fapi_CreateNv(context, nvPathExtend, "pcr", 0, "", PASSWORD);
130 goto_if_error(r, "Error Fapi_CreateNv", error);
131
132 r = Fapi_SetAuthCB(context, auth_callback, "");
133 goto_if_error(r, "Error SetPolicyAuthCallback", error);
134
135 r = Fapi_NvExtend(context, nvPathExtend, &data_src[0], NV_SIZE, "{ \"test\": \"myfile\" }");
136 goto_if_error(r, "Error Fapi_NV_EXTEN", error);
137
138 r = Fapi_Delete(context, nvPathExtend);
139 goto_if_error(r, "Error Fapi_NV_Undefine", error);
140
141 r = Fapi_Delete(context, "/");
142 goto_if_error(r, "Error Fapi_Delete", error);
143
144 SAFE_FREE(log);
145 SAFE_FREE(data_dest);
146 return EXIT_SUCCESS;
147
148 error:
149 SAFE_FREE(log);
150 SAFE_FREE(data_dest);
151 return EXIT_FAILURE;
152 }
153
154 int
155 test_invoke_fapi(FAPI_CONTEXT *context)
156 {
157 return test_fapi_nv_extend(context);
158 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14 #include <unistd.h>
15
16 #include "tss2_fapi.h"
17
18 #include "test-fapi.h"
19 #define LOGMODULE test
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 #define PASSWORD "abc"
24
25 static TSS2_RC
26 auth_callback(
27 FAPI_CONTEXT *context,
28 char const *description,
29 char **auth,
30 void *userData)
31 {
32 (void)description;
33 (void)userData;
34 *auth = strdup(PASSWORD);
35 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
36 return TSS2_RC_SUCCESS;
37 }
38
39 /** Test the FAPI function FAPI_NvIncrement.
40 *
41 * Tested FAPI commands:
42 * - Fapi_Provision()
43 * - Fapi_Import()
44 * - Fapi_CreateNv()
45 * - Fapi_SetAuthCB()
46 * - Fapi_ChangeAuth()
47 * - Fapi_Delete()
48 * - Fapi_NvIncrement()
49 *
50 * Tested Policies:
51 * - PolicyAuthValue
52 * - PolicyCommandCode
53 *
54 * @param[in,out] context The FAPI_CONTEXT.
55 * @retval EXIT_FAILURE
56 * @retval EXIT_SUCCESS
57 */
58 int
59 test_fapi_nv_increment(FAPI_CONTEXT *context)
60 {
61 TSS2_RC r;
62 char *nvPathCounter = "nv/Owner/myNV_Counter";
63 char *policy_name = "/policy/pol_nv_change_auth";
64 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_nv_change_auth.json";
65 FILE *stream = NULL;
66 char *json_policy = NULL;
67 long policy_size;
68
69 r = Fapi_Provision(context, NULL, NULL, NULL);
70 goto_if_error(r, "Error Fapi_Provision", error);
71
72 r = pcr_reset(context, 16);
73 goto_if_error(r, "Error pcr_reset", error);
74
75 stream = fopen(policy_file, "r");
76 if (!stream) {
77 LOG_ERROR("File %s does not exist", policy_file);
78 goto error;
79 }
80 fseek(stream, 0L, SEEK_END);
81 policy_size = ftell(stream);
82 fclose(stream);
83 json_policy = malloc(policy_size + 1);
84 goto_if_null(json_policy,
85 "Could not allocate memory for the JSON policy",
86 TSS2_FAPI_RC_MEMORY, error);
87 stream = fopen(policy_file, "r");
88 ssize_t ret = read(fileno(stream), json_policy, policy_size);
89 if (ret != policy_size) {
90 LOG_ERROR("IO error %s.", policy_file);
91 goto error;
92 }
93 json_policy[policy_size] = '\0';
94
95 r = Fapi_Import(context, policy_name, json_policy);
96 goto_if_error(r, "Error Fapi_Import", error);
97
98 /* Test no password, noda set */
99 r = Fapi_CreateNv(context, nvPathCounter, "counter, noda", 0, policy_name, "abc");
100 goto_if_error(r, "Error Fapi_CreateNv", error);
101
102 r = Fapi_SetAuthCB(context, auth_callback, "");
103 goto_if_error(r, "Error SetPolicyAuthCallback", error);
104
105 r = Fapi_ChangeAuth(context, nvPathCounter, "abc");
106 goto_if_error(r, "Error Fapi_CreateNv", error);
107
108 r = Fapi_Delete(context, nvPathCounter);
109 goto_if_error(r, "Error Fapi_NV_Undefine", error);
110
111 /* Test no password, noda set */
112 r = Fapi_CreateNv(context, nvPathCounter, "counter, noda", 0, "", "");
113 goto_if_error(r, "Error Fapi_CreateNv", error);
114
115 r = Fapi_NvIncrement(context, nvPathCounter);
116 goto_if_error(r, "Error Fapi_CreateNv", error);
117
118 r = Fapi_Delete(context, nvPathCounter);
119 goto_if_error(r, "Error Fapi_NV_Undefine", error);
120
121 /* Test with password noda set */
122 r = Fapi_CreateNv(context, nvPathCounter, "counter, noda", 0, "", PASSWORD);
123 goto_if_error(r, "Error Fapi_CreateNv", error);
124
125 r = Fapi_SetAuthCB(context, auth_callback, "");
126 goto_if_error(r, "Error SetPolicyAuthCallback", error);
127
128 r = Fapi_NvIncrement(context, nvPathCounter);
129 goto_if_error(r, "Error Fapi_CreateNv", error);
130
131 r = Fapi_Delete(context, nvPathCounter);
132 goto_if_error(r, "Error Fapi_NV_Undefine", error);
133
134 /* Test no password, noda clear */
135 r = Fapi_CreateNv(context, nvPathCounter, "counter", 0, "", "");
136 goto_if_error(r, "Error Fapi_CreateNv", error);
137
138 r = Fapi_NvIncrement(context, nvPathCounter);
139 goto_if_error(r, "Error Fapi_CreateNv", error);
140
141 r = Fapi_Delete(context, nvPathCounter);
142 goto_if_error(r, "Error Fapi_NV_Undefine", error);
143
144 /* Test with password noda clear */
145 r = Fapi_CreateNv(context, nvPathCounter, "counter", 0, "", PASSWORD);
146 goto_if_error(r, "Error Fapi_CreateNv", error);
147
148 r = Fapi_SetAuthCB(context, auth_callback, "");
149 goto_if_error(r, "Error SetPolicyAuthCallback", error);
150
151 r = Fapi_NvIncrement(context, nvPathCounter);
152 goto_if_error(r, "Error Fapi_CreateNv", error);
153
154 r = Fapi_Delete(context, nvPathCounter);
155 goto_if_error(r, "Error Fapi_NV_Undefine", error);
156
157
158 r = Fapi_Delete(context, "/");
159 goto_if_error(r, "Error Fapi_Delete", error);
160
161 SAFE_FREE(json_policy);
162 return EXIT_SUCCESS;
163
164 error:
165 SAFE_FREE(json_policy);
166 return EXIT_FAILURE;
167 }
168
169 int
170 test_invoke_fapi(FAPI_CONTEXT *context)
171 {
172 return test_fapi_nv_increment(context);
173 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14 #include <unistd.h>
15
16 #include "tss2_fapi.h"
17
18 #include "test-fapi.h"
19 #define LOGMODULE test
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
23 #define NV_SIZE 1200
24
25 #define PASSWORD "abc"
26
27 static char *password;
28
29 static TSS2_RC
30 auth_callback(
31 FAPI_CONTEXT *context,
32 char const *description,
33 char **auth,
34 void *userData)
35 {
36 (void)(context);
37 (void)description;
38 (void)userData;
39 *auth = strdup(PASSWORD);
40 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
41 return TSS2_RC_SUCCESS;
42 }
43
44 static TSS2_RC
45 action_callback(
46 FAPI_CONTEXT *context,
47 const char *action,
48 void *userData)
49 {
50 (void)(context);
51 (void)(userData);
52 if (strcmp(action, "myaction")) {
53 LOG_ERROR("Bad action: %s", action);
54 return TSS2_FAPI_RC_GENERAL_FAILURE;
55 }
56 return TSS2_RC_SUCCESS;
57 }
58
59 /** Test the FAPI NV functions.
60 *
61 * Tested FAPI commands:
62 * - Fapi_Provision()
63 * - Fapi_Import()
64 * - Fapi_SetPolicyActionCB()
65 * - Fapi_CreateNv()
66 * - Fapi_NvWrite()
67 * - Fapi_NvRead()
68 * - Fapi_Delete()
69 * - Fapi_SetDescription()
70 * - Fapi_GetDescription()
71 * - Fapi_SetAuthCB()
72 *
73 * Tested Policies:
74 * - PolicyAction
75 *
76 * @param[in,out] context The FAPI_CONTEXT.
77 * @retval EXIT_FAILURE
78 * @retval EXIT_SUCCESS
79 */
80 int
81 test_fapi_nv_ordinary(FAPI_CONTEXT *context)
82 {
83 TSS2_RC r;
84 char *nvPathOrdinary = "/nv/Owner/myNV";
85 uint8_t data_src[NV_SIZE];
86 uint8_t *data_dest = NULL;
87 size_t dest_size = NV_SIZE;
88 char *description1 = "nvDescription";
89 char *description2 = NULL;
90 char *policy_name = "/policy/pol_action";
91 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_action.json";
92 FILE *stream = NULL;
93 char *json_policy = NULL;
94 long policy_size;
95
96 for (int i = 0; i < NV_SIZE; i++) {
97 data_src[i] = (i % 10) + 1;
98 }
99
100 r = Fapi_Provision(context, NULL, NULL, NULL);
101 goto_if_error(r, "Error Fapi_Provision", error);
102
103 r = pcr_reset(context, 16);
104 goto_if_error(r, "Error pcr_reset", error);
105
106 stream = fopen(policy_file, "r");
107 if (!stream) {
108 LOG_ERROR("File %s does not exist", policy_file);
109 goto error;
110 }
111 fseek(stream, 0L, SEEK_END);
112 policy_size = ftell(stream);
113 fclose(stream);
114 json_policy = malloc(policy_size + 1);
115 goto_if_null(json_policy,
116 "Could not allocate memory for the JSON policy",
117 TSS2_FAPI_RC_MEMORY, error);
118 stream = fopen(policy_file, "r");
119 ssize_t ret = read(fileno(stream), json_policy, policy_size);
120 if (ret != policy_size) {
121 LOG_ERROR("IO error %s.", policy_file);
122 goto error;
123 }
124 json_policy[policy_size] = '\0';
125
126 r = Fapi_Import(context, policy_name, json_policy);
127 goto_if_error(r, "Error Fapi_Import", error);
128
129 r = Fapi_SetPolicyActionCB(context, action_callback, "");
130 goto_if_error(r, "Error Fapi_SetPolicyActionCB", error);
131
132 /* Test with policy */
133 r = Fapi_CreateNv(context, nvPathOrdinary, "noda", NV_SIZE, policy_name, "");
134 goto_if_error(r, "Error Fapi_CreateNv", error);
135
136 r = Fapi_NvWrite(context, nvPathOrdinary, &data_src[0], NV_SIZE);
137 goto_if_error(r, "Error Fapi_NvWrite", error);
138
139 r = Fapi_NvRead(context, nvPathOrdinary, &data_dest, &dest_size, NULL);
140 goto_if_error(r, "Error Fapi_NvRead", error);
141
142 if (dest_size != NV_SIZE ||
143 memcmp(data_src, data_dest, dest_size) != 0) {
144 LOG_ERROR("Error: result of nv read is wrong.");
145 goto error;
146 }
147
148 r = Fapi_Delete(context, nvPathOrdinary);
149 goto_if_error(r, "Error Fapi_NV_Undefine", error);
150 SAFE_FREE(data_dest);
151
152 /* Empty auth noda set */
153 r = Fapi_CreateNv(context, nvPathOrdinary, "noda", NV_SIZE, "", "");
154 goto_if_error(r, "Error Fapi_CreateNv", error);
155
156 r = Fapi_NvWrite(context, nvPathOrdinary, &data_src[0], NV_SIZE);
157 goto_if_error(r, "Error Fapi_NvWrite", error);
158
159 r = Fapi_NvRead(context, nvPathOrdinary, &data_dest, &dest_size, NULL);
160 goto_if_error(r, "Error Fapi_NvRead", error);
161
162 if (dest_size != NV_SIZE ||
163 memcmp(data_src, data_dest, dest_size) != 0) {
164 LOG_ERROR("Error: result of nv read is wrong.");
165 goto error;
166 }
167
168 r = Fapi_Delete(context, nvPathOrdinary);
169 goto_if_error(r, "Error Fapi_NV_Undefine", error);
170 SAFE_FREE(data_dest);
171
172 r = Fapi_SetAuthCB(context, auth_callback, "");
173 goto_if_error(r, "Error Fapi_SetAuthCB", error);
174
175 /* Password set and noda set */
176 password = PASSWORD;
177 r = Fapi_CreateNv(context, nvPathOrdinary, "", NV_SIZE, "", password);
178 goto_if_error(r, "Error Fapi_CreateNv", error);
179
180 r = Fapi_SetAuthCB(context, auth_callback, "");
181 goto_if_error(r, "Error SetPolicyAuthCallback", error);
182
183 r = Fapi_NvWrite(context, nvPathOrdinary, &data_src[0], NV_SIZE);
184 goto_if_error(r, "Error Fapi_NvWrite", error);
185
186 r = Fapi_NvRead(context, nvPathOrdinary, &data_dest, &dest_size, NULL);
187 goto_if_error(r, "Error Fapi_NvRead", error);
188
189 if (dest_size != NV_SIZE ||
190 memcmp(data_src, data_dest, dest_size) != 0) {
191 LOG_ERROR("Error: result of nv read is wrong.");
192 goto error;
193 }
194
195 r = Fapi_Delete(context, nvPathOrdinary);
196 goto_if_error(r, "Error Fapi_NV_Undefine", error);
197 SAFE_FREE(data_dest);
198
199 /* Empty auth noda clear */
200 password = "";
201 r = Fapi_CreateNv(context, nvPathOrdinary, "", NV_SIZE, "", "");
202 goto_if_error(r, "Error Fapi_CreateNv", error);
203
204 r = Fapi_SetDescription(context, nvPathOrdinary, description1);
205 goto_if_error(r, "Error Fapi_SetDescription", error);
206
207 r = Fapi_GetDescription(context, nvPathOrdinary, &description2);
208 goto_if_error(r, "Error Fapi_GetDescription", error);
209
210 if (strcmp(description1, description2) != 0) {
211 goto_if_error(r, "Different descriptions", error);
212 }
213
214 r = Fapi_NvWrite(context, nvPathOrdinary, &data_src[0], NV_SIZE);
215 goto_if_error(r, "Error Fapi_NvWrite", error);
216
217 r = Fapi_NvRead(context, nvPathOrdinary, &data_dest, &dest_size, NULL);
218 goto_if_error(r, "Error Fapi_NvRead", error);
219
220 if (dest_size != NV_SIZE ||
221 memcmp(data_src, data_dest, dest_size) != 0) {
222 LOG_ERROR("Error: result of nv read is wrong.");
223 goto error;
224 }
225
226 r = Fapi_Delete(context, nvPathOrdinary);
227 goto_if_error(r, "Error Fapi_NV_Undefine", error);
228 SAFE_FREE(data_dest);
229
230 /* Password set and noda clear */
231 password = PASSWORD;
232 r = Fapi_CreateNv(context, nvPathOrdinary, "", NV_SIZE, "", password);
233 goto_if_error(r, "Error Fapi_CreateNv", error);
234
235 r = Fapi_SetAuthCB(context, auth_callback, "");
236 goto_if_error(r, "Error SetPolicyAuthCallback", error);
237
238 r = Fapi_NvWrite(context, nvPathOrdinary, &data_src[0], NV_SIZE);
239 goto_if_error(r, "Error Fapi_NvWrite", error);
240
241 r = Fapi_NvRead(context, nvPathOrdinary, &data_dest, &dest_size, NULL);
242 goto_if_error(r, "Error Fapi_NvRead", error);
243
244 if (dest_size != NV_SIZE ||
245 memcmp(data_src, data_dest, dest_size) != 0) {
246 LOG_ERROR("Error: result of nv read is wrong.");
247 goto error;
248 }
249 r = Fapi_Delete(context, nvPathOrdinary);
250 goto_if_error(r, "Error Fapi_NV_Undefine", error);
251
252 r = Fapi_Delete(context, "/");
253 goto_if_error(r, "Error Fapi_Delete", error);
254
255 SAFE_FREE(data_dest);
256 SAFE_FREE(description2);
257 SAFE_FREE(json_policy);
258 return EXIT_SUCCESS;
259
260 error:
261 SAFE_FREE(data_dest);
262 SAFE_FREE(description2);
263 SAFE_FREE(json_policy);
264 return EXIT_FAILURE;
265 }
266
267 int
268 test_invoke_fapi(FAPI_CONTEXT *context)
269 {
270 return test_fapi_nv_ordinary(context);
271 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14
15 #include "tss2_fapi.h"
16
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 #define PASSWORD "abc"
22
23 static TSS2_RC
24 auth_callback(
25 FAPI_CONTEXT *context,
26 char const *description,
27 char **auth,
28 void *userData)
29 {
30 (void)description;
31 (void)userData;
32 *auth = strdup(PASSWORD);
33 return_if_null(*auth, "Out of memory.", TSS2_FAPI_RC_MEMORY);
34 return TSS2_RC_SUCCESS;
35 }
36
37 /** Test the FAPI function Fapi_NvSetBits.
38 *
39 * Tested FAPI commands:
40 * - Fapi_Provision()
41 * - Fapi_CreateNv()
42 * - Fapi_NvSetBits()
43 * - Fapi_Delete()
44 * - Fapi_SetAuthCB()
45 *
46 * @param[in,out] context The FAPI_CONTEXT.
47 * @retval EXIT_FAILURE
48 * @retval EXIT_SUCCESS
49 */
50 int
51 test_fapi_nv_set_bits(FAPI_CONTEXT *context)
52 {
53 TSS2_RC r;
54 char *nvPathBitMap = "/nv/Owner/myNV_BitMap";
55
56 r = Fapi_Provision(context, NULL, NULL, NULL);
57 goto_if_error(r, "Error Fapi_Provision", error);
58
59 /* Test no password, noda set */
60 r = Fapi_CreateNv(context, nvPathBitMap, "bitfield, noda", 0, "", "");
61 goto_if_error(r, "Error Fapi_CreateNv", error);
62
63 uint64_t bitmap = 0x0102030405060608;
64
65 r = Fapi_NvSetBits(context, nvPathBitMap, bitmap);
66 goto_if_error(r, "Error Fapi_SetBits", error);
67
68 r = Fapi_Delete(context, nvPathBitMap);
69 goto_if_error(r, "Error Fapi_Delete", error);
70
71 /* Test with password noda set */
72 r = Fapi_CreateNv(context, nvPathBitMap, "bitfield, noda", 0, "", PASSWORD);
73 goto_if_error(r, "Error Fapi_CreateNv", error);
74
75 r = Fapi_SetAuthCB(context, auth_callback, "");
76 goto_if_error(r, "Error SetPolicyAuthCallback", error);
77
78 r = Fapi_NvSetBits(context, nvPathBitMap, bitmap);
79 goto_if_error(r, "Error Fapi_CreateNv", error);
80
81 r = Fapi_Delete(context, nvPathBitMap);
82 goto_if_error(r, "Error Fapi_Delete", error);
83
84 /* Cleanup */
85 r = Fapi_Delete(context, "/HS/SRK");
86 goto_if_error(r, "Error Fapi_Delete", error);
87
88 r = Fapi_Provision(context, NULL, NULL, NULL);
89 goto_if_error(r, "Error Fapi_Provision", error);
90
91 /* Test no password, noda set */
92 r = Fapi_CreateNv(context, nvPathBitMap, "bitfield, noda", 0, "", "");
93 goto_if_error(r, "Error Fapi_CreateNv", error);
94
95 r = Fapi_NvSetBits(context, nvPathBitMap, bitmap);
96 goto_if_error(r, "Error Fapi_NvSetbits", error);
97
98 r = Fapi_Delete(context, nvPathBitMap);
99 goto_if_error(r, "Error Fapi_Delete", error);
100
101 /* Test with password noda set */
102 r = Fapi_CreateNv(context, nvPathBitMap, "bitfield, noda", 0, "", PASSWORD);
103 goto_if_error(r, "Error Fapi_CreateNv", error);
104
105 r = Fapi_SetAuthCB(context, auth_callback, "");
106 goto_if_error(r, "Error SetPolicyAuthCallback", error);
107
108 r = Fapi_NvSetBits(context, nvPathBitMap, bitmap);
109 goto_if_error(r, "Error Fapi_SetBits", error);
110
111 r = Fapi_Delete(context, nvPathBitMap);
112 goto_if_error(r, "Error Fapi_Delete", error);
113
114
115 r = Fapi_Delete(context, "/");
116
117 goto_if_error(r, "Error Fapi_Delete", error);
118
119 return EXIT_SUCCESS;
120
121 error:
122 Fapi_Delete(context, "/HS/SRK");
123 return EXIT_FAILURE;
124 }
125
126 int
127 test_invoke_fapi(FAPI_CONTEXT *context)
128 {
129 return test_fapi_nv_set_bits(context);
130 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <inttypes.h>
13 #include <string.h>
14 #include <unistd.h>
15
16 #include "tss2_fapi.h"
17
18 #define LOGMODULE test
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22 #define NV_SIZE 10
23
24 /** Test the FAPI policy PolicyNvWritten.
25 *
26 * Tested FAPI commands:
27 * - Fapi_Provision()
28 * - Fapi_CreateNv()
29 * - Fapi_SetAppData()
30 * - Fapi_GetAppData()
31 * - Fapi_NvWrite()
32 * - Fapi_Delete()
33 *
34 * Tested Policies:
35 * - PolicyNvWritten
36 *
37 * @param[in,out] context The FAPI_CONTEXT.
38 * @retval EXIT_FAILURE
39 * @retval EXIT_SUCCESS
40 */
41 int
42 test_fapi_nv_written_policy(FAPI_CONTEXT *context)
43 {
44 TSS2_RC r;
45 char *nvPathOrdinary = "/nv/Owner/myNV";
46 char *policy_name = "/policy/pol_nv_written";
47 char *policy_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_nv_written.json";
48 FILE *stream = NULL;
49 char *json_policy = NULL;
50 long policy_size;
51 uint8_t *appData = NULL;
52 size_t appDataSize;
53
54 r = Fapi_Provision(context, NULL, NULL, NULL);
55 goto_if_error(r, "Error Fapi_Provision", error);
56
57 uint8_t data_src[NV_SIZE] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
58
59 stream = fopen(policy_file, "r");
60 if (!stream) {
61 LOG_ERROR("File %s does not exist", policy_file);
62 goto error;
63 }
64 fseek(stream, 0L, SEEK_END);
65 policy_size = ftell(stream);
66 fclose(stream);
67 json_policy = malloc(policy_size + 1);
68 goto_if_null(json_policy,
69 "Could not allocate memory for the JSON policy",
70 TSS2_FAPI_RC_MEMORY, error);
71
72 stream = fopen(policy_file, "r");
73 ssize_t ret = read(fileno(stream), json_policy, policy_size);
74 if (ret != policy_size) {
75 LOG_ERROR("IO error %s.", policy_file);
76 goto error;
77 }
78 json_policy[policy_size] = '\0';
79
80 r = Fapi_Import(context, policy_name, json_policy);
81 goto_if_error(r, "Error Fapi_Import", error);
82
83 /* Empty auth noda set */
84 r = Fapi_CreateNv(context, nvPathOrdinary, "noda", 10, policy_name, "");
85 goto_if_error(r, "Error Fapi_CreateNv", error);
86
87 r = Fapi_SetAppData(context, nvPathOrdinary, data_src, NV_SIZE);
88 goto_if_error(r, "Error Fapi_SetAppData", error);
89
90 r = Fapi_GetAppData(context, nvPathOrdinary, &appData, &appDataSize);
91 goto_if_error(r, "Error Fapi_GetAppData", error);
92
93 if (NV_SIZE != appDataSize ||
94 memcmp(appData, &data_src[0], appDataSize) != 0) {
95 LOG_ERROR("Error: AppData equal to origin");
96 goto error;
97 }
98
99 r = Fapi_NvWrite(context, nvPathOrdinary, &data_src[0], NV_SIZE);
100 goto_if_error(r, "Error Fapi_NvWrite", error);
101
102 r = Fapi_Delete(context, nvPathOrdinary);
103 goto_if_error(r, "Error Fapi_NV_Undefine", error);
104
105 r = Fapi_Delete(context, "/");
106 goto_if_error(r, "Error Fapi_Delete", error);
107
108
109 SAFE_FREE(json_policy);
110 SAFE_FREE(appData);
111
112 return EXIT_SUCCESS;
113
114 error:
115 SAFE_FREE(json_policy);
116 SAFE_FREE(appData);
117
118 return EXIT_FAILURE;
119 }
120
121 int
122 test_invoke_fapi(FAPI_CONTEXT *context)
123 {
124 return test_fapi_nv_written_policy(context);
125 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <inttypes.h>
14
15 #include "tss2_fapi.h"
16
17 #include "test-fapi.h"
18 #define LOGMODULE test
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22 #define EVENT_SIZE 10
23
24 /* This is a list of expected value from the test. Possible returns (for different PCR bank
25 configurations) are concatenated into a long string and the test uses strstr() to find a match.*/
26 const char *log_exp[] = {
27 "[\n\
28 {\n\
29 \"recnum\":1,\n\
30 \"pcr\":16,\n\
31 \"digests\":[\n\
32 {\n\
33 \"hashAlg\":\"SHA1\",\n\
34 \"digest\":\"494179714a6cd627239dfededf2de9ef994caf03\"\n\
35 },\n\
36 {\n\
37 \"hashAlg\":\"SHA256\",\n\
38 \"digest\":\"1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3\"\n\
39 },\n\
40 {\n\
41 \"hashAlg\":\"SHA384\",\n\
42 \"digest\":\"182e95266adff49059e706c61483478fe0688150c8d08b95fab5cfde961f12d903aaf44104af4ce72ba6a4bf20302b2e\"\n\
43 },\n\
44 {\n\
45 \"hashAlg\":\"SHA512\",\n\
46 \"digest\":\"0f89ee1fcb7b0a4f7809d1267a029719004c5a5e5ec323a7c3523a20974f9a3f202f56fadba4cd9e8d654ab9f2e96dc5c795ea176fa20ede8d854c342f903533\"\n\
47 }\n\
48 ],\n\
49 \"type\":\"tss2\",\n\
50 \"sub_event\":{\n\
51 \"data\":\"00010203040506070809\",\n\
52 \"event\":{\n\
53 \"test\":\"myfile\"\n\
54 }\n\
55 }\n\
56 }\n\
57 ]",
58 "[\n\
59 {\n\
60 \"recnum\":1,\n\
61 \"pcr\":16,\n\
62 \"digests\":[\n\
63 {\n\
64 \"hashAlg\":\"SHA1\",\n\
65 \"digest\":\"494179714a6cd627239dfededf2de9ef994caf03\"\n\
66 },\n\
67 {\n\
68 \"hashAlg\":\"SHA256\",\n\
69 \"digest\":\"1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3\"\n\
70 },\n\
71 {\n\
72 \"hashAlg\":\"SHA384\",\n\
73 \"digest\":\"182e95266adff49059e706c61483478fe0688150c8d08b95fab5cfde961f12d903aaf44104af4ce72ba6a4bf20302b2e\"\n\
74 }\n\
75 ],\n\
76 \"type\":\"tss2\",\n\
77 \"sub_event\":{\n\
78 \"data\":\"00010203040506070809\",\n\
79 \"event\":{\n\
80 \"test\":\"myfile\"\n\
81 }\n\
82 }\n\
83 }\n\
84 ]",
85 "[\n\
86 {\n\
87 \"recnum\":1,\n\
88 \"pcr\":16,\n\
89 \"digests\":[\n\
90 {\n\
91 \"hashAlg\":\"SHA1\",\n\
92 \"digest\":\"494179714a6cd627239dfededf2de9ef994caf03\"\n\
93 },\n\
94 {\n\
95 \"hashAlg\":\"SHA256\",\n\
96 \"digest\":\"1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3\"\n\
97 }\n\
98 ],\n\
99 \"type\":\"tss2\",\n\
100 \"sub_event\":{\n\
101 \"data\":\"00010203040506070809\",\n\
102 \"event\":{\n\
103 \"test\":\"myfile\"\n\
104 }\n\
105 }\n\
106 }\n\
107 ]",
108 "[\n\
109 {\n\
110 \"recnum\":1,\n\
111 \"pcr\":16,\n\
112 \"digests\":[\n\
113 {\n\
114 \"hashAlg\":\"SHA1\",\n\
115 \"digest\":\"494179714a6cd627239dfededf2de9ef994caf03\"\n\
116 }\n\
117 ],\n\
118 \"type\":\"tss2\",\n\
119 \"sub_event\":{\n\
120 \"data\":\"00010203040506070809\",\n\
121 \"event\":{\n\
122 \"test\":\"myfile\"\n\
123 }\n\
124 }\n\
125 }\n\
126 ]",
127 "[\n\
128 {\n\
129 \"recnum\":1,\n\
130 \"pcr\":16,\n\
131 \"digests\":[\n\
132 {\n\
133 \"hashAlg\":\"SHA256\",\n\
134 \"digest\":\"1f825aa2f0020ef7cf91dfa30da4668d791c5d4824fc8e41354b89ec05795ab3\"\n\
135 }\n\
136 ],\n\
137 \"type\":\"tss2\",\n\
138 \"sub_event\":{\n\
139 \"data\":\"00010203040506070809\",\n\
140 \"event\":{\n\
141 \"test\":\"myfile\"\n\
142 }\n\
143 }\n\
144 }\n\
145 ]" };
146
147 /** Test the FAPI function FAPI_PcrExtend and Read.
148 *
149 * Tested FAPI commands:
150 * - Fapi_Provision()
151 * - Fapi_PcrExtend()
152 * - Fapi_PcrRead()
153 * - Fapi_Delete()
154 *
155 * @param[in,out] context The FAPI_CONTEXT.
156 * @retval EXIT_FAILURE
157 * @retval EXIT_SUCCESS
158 */
159 int
160 test_fapi_pcr_test(FAPI_CONTEXT *context)
161 {
162 TSS2_RC r;
163 size_t i;
164 uint8_t data[EVENT_SIZE] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
165 size_t pcr_digest_size;
166 uint8_t *pcr_digest = NULL;
167 char *log = NULL;
168
169 r = Fapi_Provision(context, NULL, NULL, NULL);
170 goto_if_error(r, "Error Fapi_Provision", error);
171
172 r = pcr_reset(context, 16);
173 goto_if_error(r, "Error pcr_reset", error);
174
175 r = Fapi_PcrExtend(context, 16, data, EVENT_SIZE, "{ \"test\": \"myfile\" }");
176 goto_if_error(r, "Error Fapi_PcrExtend", error);
177
178 r = Fapi_PcrRead(context, 16, &pcr_digest,
179 &pcr_digest_size, &log);
180 goto_if_error(r, "Error Fapi_PcrRead", error);
181
182 for (i = 0; i < ( sizeof(log_exp) / sizeof(log_exp[0]) ); i++)
183 if (strcmp(log_exp[i], log) == 0)
184 break;
185 if (i >= 3) {
186 LOG_ERROR("Log mismatch. Received: %s", log);
187 goto error;
188 }
189
190 fprintf(stderr, "\n\Event Log:\n%s\n", log);
191
192 SAFE_FREE(pcr_digest);
193 SAFE_FREE(log);
194 r = pcr_reset(context, 16);
195 goto_if_error(r, "Error pcr_reset", error);
196
197 r = Fapi_PcrRead(context, 16, &pcr_digest,
198 &pcr_digest_size, &log);
199 goto_if_error(r, "Error Fapi_PcrRead", error);
200
201 r = Fapi_Delete(context, "/HS/SRK");
202 goto_if_error(r, "Error Fapi_Delete", error);
203
204 SAFE_FREE(pcr_digest);
205 SAFE_FREE(log);
206 return EXIT_SUCCESS;
207
208 error:
209 Fapi_Delete(context, "/HS/SRK");
210 SAFE_FREE(pcr_digest);
211 SAFE_FREE(log);
212 return EXIT_FAILURE;
213 }
214
215 int
216 test_invoke_fapi(FAPI_CONTEXT *context)
217 {
218 return test_fapi_pcr_test(context);
219 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11
12 #include "tss2_fapi.h"
13
14 #include "test-fapi.h"
15
16 #define LOGMODULE test
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20 /** Test the FAPI functions for platform certificates.
21 *
22 * Tested FAPI commands:
23 * - Fapi_Provision()
24 * - Fapi_GetPlatformCertificates()
25 * - Fapi_Delete()
26 *
27 * @param[in,out] context The FAPI_CONTEXT.
28 * @retval EXIT_FAILURE
29 * @retval EXIT_SUCCESS
30 */
31 int
32 test_fapi_platform_certificates(FAPI_CONTEXT *context)
33 {
34 TSS2_RC r;
35 uint8_t *certs = NULL;
36 size_t certsSize = 0;
37
38 r = Fapi_Provision(context, NULL, NULL, NULL);
39 goto_if_error(r, "Error Fapi_Provision", error);
40
41 r = Fapi_GetPlatformCertificates(context, &certs, &certsSize);
42 if (r == TSS2_FAPI_RC_NO_CERT)
43 goto skip;
44 goto_if_error(r, "Error Fapi_GetPlatformCertificates", error);
45
46 Fapi_Free(certs);
47
48 /* Cleanup */
49 r = Fapi_Delete(context, "/HS/SRK");
50 goto_if_error(r, "Error Fapi_Delete", error);
51
52 return EXIT_SUCCESS;
53
54 error:
55 Fapi_Delete(context, "/HS/SRK");
56 return EXIT_FAILURE;
57
58 skip:
59 Fapi_Delete(context, "/HS/SRK");
60 return EXIT_SKIP;
61 }
62
63 int
64 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
65 {
66 return test_fapi_platform_certificates(fapi_context);
67 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <json-c/json.h>
16 #include <json-c/json_util.h>
17 #include <json-c/json_tokener.h>
18
19 #include "tss2_fapi.h"
20
21 #include "test-fapi.h"
22 #define LOGMODULE test
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 #define EVENT_SIZE 10
27
28 /** Test the FAPI functions for quote commands.
29 *
30 * Tested FAPI commands:
31 * - Fapi_Provision()
32 * - Fapi_CreateKey()
33 * - Fapi_PcrExtend()
34 * - Fapi_Quote()
35 * - Fapi_ExportKey()
36 * - Fapi_Import()
37 * - Fapi_PcrRead()
38 * - Fapi_VerifyQuote()
39 * - Fapi_List()
40 * - Fapi_Delete()
41 *
42 * @param[in,out] context The FAPI_CONTEXT.
43 * @retval EXIT_FAILURE
44 * @retval EXIT_SUCCESS
45 */
46 int
47 test_fapi_quote(FAPI_CONTEXT *context)
48 {
49 TSS2_RC r;
50 json_object *jso = NULL;
51 char *pubkey_pem = NULL;
52 uint8_t *signature = NULL;
53 char *quoteInfo = NULL;
54 char *pcrEventLog = NULL;
55 char *certificate = NULL;
56 char *export_data = NULL;
57 json_object *jso_public = NULL;
58 uint8_t *pcr_digest = NULL;
59 char *log = NULL;
60 char *pathlist = NULL;
61
62 uint8_t data[EVENT_SIZE] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
63 size_t signatureSize = 0;
64 uint32_t pcrList[1] = { 16 };
65 size_t pcr_digest_size = 0;
66
67 r = Fapi_Provision(context, NULL, NULL, NULL);
68
69 goto_if_error(r, "Error Fapi_Provision", error);
70
71 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", "sign,noDa", "", NULL);
72 goto_if_error(r, "Error Fapi_CreateKey", error);
73
74 uint8_t qualifyingData[20] = {
75 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
76 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
77 };
78
79 r = pcr_reset(context, 16);
80 goto_if_error(r, "Error pcr_reset", error);
81
82 r = Fapi_PcrExtend(context, 16, data, EVENT_SIZE, "{ \"test\": \"myfile\" }");
83 goto_if_error(r, "Error Fapi_PcrExtend", error);
84
85 r = Fapi_Quote(context, pcrList, 1, "HS/SRK/mySignKey",
86 "TPM-Quote",
87 qualifyingData, 20,
88 &quoteInfo,
89 &signature, &signatureSize,
90 &pcrEventLog, &certificate);
91 goto_if_error(r, "Error Fapi_Quote", error);
92
93 r = Fapi_ExportKey(context, "HS/SRK/mySignKey", NULL, &export_data);
94 goto_if_error(r, "Export.", error);
95
96 jso = json_tokener_parse(export_data);
97
98 LOG_INFO("\nExported: %s\n", export_data);
99
100 if (!jso || !json_object_object_get_ex(jso, "pem_ext_public", &jso_public)) {
101 LOG_ERROR("No public key eyported.");
102 goto error;
103 }
104 pubkey_pem = strdup(json_object_get_string(jso_public));
105 if (!pubkey_pem) {
106 LOG_ERROR("Out of memory.");
107 goto error;
108 }
109
110 r = Fapi_Import(context, "/ext/myExtPubKey", pubkey_pem);
111 goto_if_error(r, "Error Fapi_Import", error);
112
113 r = Fapi_PcrRead(context, 16, &pcr_digest,
114 &pcr_digest_size, &log);
115 goto_if_error(r, "Error Fapi_PcrRead", error);
116
117 LOG_INFO("\nLog:\n%s\n", log);
118 LOG_INFO("Quote Info:\n%s\n", quoteInfo);
119
120 r = Fapi_VerifyQuote(context, "HS/SRK/mySignKey",
121 qualifyingData, 20, quoteInfo,
122 signature, signatureSize, log);
123 goto_if_error(r, "Error Fapi_Verfiy_Quote", error);
124
125 r = Fapi_Delete(context, "/HS/SRK");
126 goto_if_error(r, "Error Fapi_Delete", error);
127
128 r = Fapi_List(context, "/", &pathlist);
129 goto_if_error(r, "Pathlist", error);
130
131 json_object_put(jso);
132 SAFE_FREE(pubkey_pem);
133 SAFE_FREE(signature);
134 SAFE_FREE(quoteInfo);
135 SAFE_FREE(pcrEventLog);
136 SAFE_FREE(certificate);
137 SAFE_FREE(export_data);
138 SAFE_FREE(pcr_digest);
139 SAFE_FREE(log);
140 SAFE_FREE(pathlist);
141 return EXIT_SUCCESS;
142
143 error:
144 if (jso)
145 json_object_put(jso);
146 SAFE_FREE(pubkey_pem);
147 SAFE_FREE(signature);
148 SAFE_FREE(quoteInfo);
149 SAFE_FREE(pcrEventLog);
150 SAFE_FREE(certificate);
151 SAFE_FREE(export_data);
152 SAFE_FREE(pcr_digest);
153 SAFE_FREE(log);
154 SAFE_FREE(pathlist);
155 return EXIT_FAILURE;
156 }
157
158 int
159 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
160 {
161 return test_fapi_quote(fapi_context);
162 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "tss2_fapi.h"
14
15 #include "test-fapi.h"
16 #define LOGMODULE test
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20
21 /** Test the FAPI functions for sealing.
22 *
23 * Tested FAPI commands:
24 * - Fapi_Provision()
25 * - Fapi_CreateSeal()
26 * - Fapi_Unseal()
27 * - Fapi_Delete()
28 *
29 * @param[in,out] context The FAPI_CONTEXT.
30 * @retval EXIT_FAILURE
31 * @retval EXIT_SUCCESS
32 */
33 int
34 test_fapi_unseal(FAPI_CONTEXT *context)
35 {
36 TSS2_RC r;
37 size_t resultSize;
38 uint8_t *result = NULL;
39
40 TPM2B_DIGEST digest = {
41 .size = 20,
42 .buffer = {
43 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
44 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
45 }
46 };
47
48 r = Fapi_Provision(context, NULL, NULL, NULL);
49 goto_if_error(r, "Error Fapi_Provision", error);
50
51 r = Fapi_CreateSeal(context, "/HS/SRK/mySealObject", "noDa",
52 digest.size,
53 "", "", &digest.buffer[0]);
54 goto_if_error(r, "Error Fapi_CreateSeal", error);
55
56 r = Fapi_Unseal(context, "/HS/SRK/mySealObject", &result,
57 &resultSize);
58 goto_if_error(r, "Error Fapi_CreateSeal", error);
59
60 r = Fapi_Delete(context, "/HS/SRK/mySealObject");
61 goto_if_error(r, "Error Fapi_Delete", error);
62
63 r = Fapi_Delete(context, "/HS/SRK");
64 goto_if_error(r, "Error Fapi_Delete", error);
65
66 if (resultSize != digest.size ||
67 memcmp(result, &digest.buffer[0], resultSize) != 0) {
68 LOG_ERROR("Error: unealed data not equal to origin");
69 goto error;
70 }
71
72 SAFE_FREE(result);
73 return EXIT_SUCCESS;
74
75 error:
76 SAFE_FREE(result);
77 return EXIT_FAILURE;
78 }
79
80 int
81 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
82 {
83 return test_fapi_unseal(fapi_context);
84 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 *******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/stat.h>
15
16 #include "tss2_esys.h"
17 #include "tss2_fapi.h"
18
19 #include "test-fapi.h"
20
21 #define LOGDEFAULT LOGLEVEL_INFO
22 #define LOGMODULE test
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 #ifndef FAPI_PROFILE
27 #define FAPI_PROFILE "P_ECC"
28 #endif /* FAPI_PROFILE */
29
30 char *fapi_profile = NULL;
31
32 TSS2_RC
33 pcr_reset(FAPI_CONTEXT *context, UINT32 pcr)
34 {
35 TSS2_RC r;
36 TSS2_TCTI_CONTEXT *tcti;
37 ESYS_CONTEXT *esys;
38
39 r = Fapi_GetTcti(context, &tcti);
40 goto_if_error(r, "Error Fapi_GetTcti", error);
41
42 r = Esys_Initialize(&esys, tcti, NULL);
43 goto_if_error(r, "Error Fapi_GetTcti", error);
44
45 r = Esys_PCR_Reset(esys, pcr,
46 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE);
47 Esys_Finalize(&esys);
48 goto_if_error(r, "Error Eys_PCR_Reset", error);
49
50 error:
51 return r;
52 }
53
54 /**
55 * This program is a template for integration tests (ones that use the TCTI,
56 * the ESAPI, and FAPI contexts / API directly). It does nothing more than
57 * parsing command line options that allow the caller (likely a script)
58 * to specifywhich TCTI to use for the test using getenv("TPM20TEST_TCTI").
59 */
60 int
61 main(int argc, char *argv[])
62 {
63 TSS2_RC rc;
64 FAPI_CONTEXT *fapi_context = NULL;
65
66 int ret, size;
67 char *config = NULL;
68 char *config_path = NULL;
69 char *config_env = NULL;
70 char *remove_cmd = NULL;
71 char *system_dir = NULL;
72
73 FILE *config_file;
74
75 char template[] = "/tmp/fapi_tmpdir.XXXXXX";
76
77 char *tmpdir = mkdtemp(template);
78 if (!tmpdir) {
79 LOG_ERROR("No temp dir created");
80 return EXIT_ERROR;
81 }
82
83 fapi_profile = FAPI_PROFILE;
84
85 /* First we construct a fapi config file */
86 #if defined(FAPI_NONTPM)
87 size = asprintf(&config, "{\n"
88 " \"profile_name\": \"" FAPI_PROFILE "\",\n"
89 " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
90 " \"user_dir\": \"%s/user/dir\",\n"
91 " \"system_dir\": \"%s/system_dir\",\n"
92 " \"system_pcrs\" : [],\n"
93 " \"log_dir\" : \"%s\",\n"
94 " \"tcti\": \"none\",\n"
95 "}\n",
96 tmpdir, tmpdir, tmpdir);
97 #elif defined(FAPI_TEST_FINGERPRINT)
98 size = asprintf(&config, "{\n"
99 " \"profile_name\": \"" FAPI_PROFILE "\",\n"
100 " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
101 " \"user_dir\": \"%s/user/dir\",\n"
102 " \"system_dir\": \"%s/system_dir\",\n"
103 " \"system_pcrs\" : [],\n"
104 " \"log_dir\" : \"%s\",\n"
105 " \"tcti\": \"%s\",\n"
106 #if defined(FAPI_TEST_EK_CERT_LESS)
107 " \"ek_cert_less\": \"yes\",\n"
108 #else
109 " \"ek_fingerprint\": %s,\n"
110 #endif
111 "}\n",
112 tmpdir, tmpdir, tmpdir,
113 getenv("TPM20TEST_TCTI"),
114 getenv("FAPI_TEST_FINGERPRINT"));
115 #elif defined(FAPI_TEST_CERTIFICATE)
116 size = asprintf(&config, "{\n"
117 " \"profile_name\": \"" FAPI_PROFILE "\",\n"
118 " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
119 " \"user_dir\": \"%s/user/dir\",\n"
120 " \"system_dir\": \"%s/system_dir\",\n"
121 " \"system_pcrs\" : [],\n"
122 " \"log_dir\" : \"%s\",\n"
123 " \"tcti\": \"%s\",\n"
124 #if defined(FAPI_TEST_EK_CERT_LESS)
125 " \"ek_cert_less\": \"yes\",\n"
126 #else
127 " \"ek_cert_file\": \"%s\",\n"
128 #endif
129 "}\n",
130 tmpdir, tmpdir, tmpdir,
131 getenv("TPM20TEST_TCTI"),
132 getenv("FAPI_TEST_CERTIFICATE"));
133 #elif defined(FAPI_TEST_FINGERPRINT_ECC)
134 size = asprintf(&config, "{\n"
135 " \"profile_name\": \"" FAPI_PROFILE "\",\n"
136 " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
137 " \"user_dir\": \"%s/user/dir\",\n"
138 " \"system_dir\": \"%s/system_dir\",\n"
139 " \"system_pcrs\" : [],\n"
140 " \"log_dir\" : \"%s\",\n"
141 " \"tcti\": \"%s\",\n"
142 #if defined(FAPI_TEST_EK_CERT_LESS)
143 " \"ek_cert_less\": \"yes\",\n"
144 #else
145 " \"ek_fingerprint\": %s,\n"
146 #endif
147 "}\n",
148 tmpdir, tmpdir, tmpdir,
149 getenv("TPM20TEST_TCTI"),
150 getenv("FAPI_TEST_FINGERPRINT_ECC"));
151 #elif defined(FAPI_TEST_CERTIFICATE_ECC)
152 size = asprintf(&config, "{\n"
153 " \"profile_name\": \"" FAPI_PROFILE "\",\n"
154 " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
155 " \"user_dir\": \"%s/user/dir\",\n"
156 " \"system_dir\": \"%s/system_dir\",\n"
157 " \"system_pcrs\" : [],\n"
158 " \"log_dir\" : \"%s\",\n"
159 " \"tcti\": \"%s\",\n"
160 #if defined(FAPI_TEST_EK_CERT_LESS)
161 " \"ek_cert_less\": \"yes\",\n"
162 #else
163 " \"ek_cert_file\": \"%s\",\n"
164 #endif
165 "}\n",
166 tmpdir, tmpdir, tmpdir,
167 getenv("TPM20TEST_TCTI"),
168 getenv("FAPI_TEST_CERTIFICATE_ECC"));
169 #else /* FAPI_NONTPM */
170 size = asprintf(&config, "{\n"
171 " \"profile_name\": \"" FAPI_PROFILE "\",\n"
172 " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
173 " \"user_dir\": \"%s/user/dir\",\n"
174 " \"system_dir\": \"%s/system_dir\",\n"
175 " \"system_pcrs\" : [],\n"
176 " \"log_dir\" : \"%s\",\n"
177 " \"tcti\": \"%s\",\n"
178 #if defined(FAPI_TEST_EK_CERT_LESS)
179 " \"ek_cert_less\": \"yes\",\n"
180 #endif
181 "}\n",
182 tmpdir, tmpdir, tmpdir,
183 getenv("TPM20TEST_TCTI"));
184 #endif /* FAPI_NONTPM */
185 if (size < 0) {
186 LOG_ERROR("Out of memory");
187 ret = EXIT_ERROR;
188 goto error;
189 }
190
191 size = asprintf(&system_dir, "%s/system_dir/", tmpdir);
192 if (size < 0) {
193 LOG_ERROR("Out of memory");
194 ret = EXIT_ERROR;
195 goto error;
196 }
197
198 int rc_mkdir = mkdir(system_dir, 0777);
199 if (rc_mkdir != 0) {
200 LOG_ERROR("mkdir not possible: %i %s", rc_mkdir, system_dir);
201 ret = EXIT_ERROR;
202 goto error;
203 }
204
205 if (size < 0) {
206 LOG_ERROR("Out of memory");
207 ret = EXIT_ERROR;
208 goto error;
209 }
210 LOG_INFO("Using config:\n%s", config);
211
212 /* We construct the path for the config file */
213 size = asprintf(&config_path, "%s/fapi-config.json", tmpdir);
214 if (size < 0) {
215 LOG_ERROR("Out of memory");
216 ret = EXIT_ERROR;
217 goto error;
218 }
219
220 /* We write the config file to disk */
221 config_file = fopen(config_path, "w");
222 if (!config_file) {
223 LOG_ERROR("Opening config file for writing");
224 perror(config_path);
225 ret = EXIT_ERROR;
226 goto error;
227 }
228 size = fprintf(config_file, "%s", config);
229 fclose(config_file);
230 if (size < 0) {
231 LOG_ERROR("Writing config file");
232 perror(config_path);
233 ret = EXIT_ERROR;
234 goto error;
235 }
236
237 /* We set the environment variable for FAPI to consume the config file */
238 size = asprintf(&config_env, "TSS2_FAPICONF=%s", config_path);
239 if (size < 0) {
240 LOG_ERROR("Out of memory");
241 ret = EXIT_ERROR;
242 goto error;
243 }
244 putenv(config_env);
245
246 /***********
247 * Call FAPI
248 ***********/
249
250 rc = Fapi_Initialize(&fapi_context, NULL);
251 if (rc != TSS2_RC_SUCCESS) {
252 LOG_ERROR("Esys_Initialize FAILED! Response Code : 0x%x", rc);
253 ret = EXIT_FAILURE;
254 goto error;
255 }
256
257 ret = test_invoke_fapi(fapi_context);
258 LOG_INFO("Test returned %i", ret);
259 if (ret) goto error;
260
261 size = asprintf(&remove_cmd, "rm -r -f %s", tmpdir);
262 if (size < 0) {
263 LOG_ERROR("Out of memory");
264 ret = EXIT_ERROR;
265 goto error;
266 }
267 if (system(remove_cmd) != 0) {
268 LOG_ERROR("Directory %s can't be deleted.", tmpdir);
269 ret = EXIT_ERROR;
270 goto error;
271 }
272
273 error:
274 Fapi_Finalize(&fapi_context);
275
276 if (system_dir) free(system_dir);
277 if (config) free(config);
278 if (config_path) free(config_path);
279 if (config_env) free(config_env);
280 if (remove_cmd) free(remove_cmd);
281
282 return ret;
283 }
0 /*
1 * SPDX-License-Identifier: BSD-2-Clause
2 * Copyright (c) 2019, Intel Corporation
3 */
4
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <inttypes.h>
10 #include <stdbool.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "tss2_sys.h"
16
17 #include "context-util.h"
18 #include "sapi-util.h"
19 #include "session-util.h"
20 #define LOGMODULE test
21 #include "util/log.h"
22
23 #define TPM20_INDEX_PASSWORD_TEST 0x01500020
24
25 #define NV_DATA_SIZE 4
26 #define NV_DATA { 0x00, 0xff, 0x55, 0xaa }
27 #define SECRET_SIZE 13
28 #define SECRET_DATA { 's', 'h', 'a', 'r', 'e', 'd', ' ', \
29 's', 'e', 'c', 'r', 'e', 't', }
30
31 TSS2_RC
32 create_policy (TSS2_SYS_CONTEXT *sys_ctx,
33 TPM2B_DIGEST *authPolicy)
34 {
35 TSS2_RC rc;
36 SESSION *trialPolicySession = NULL;
37 TPM2B_NONCE nonceCaller = { 0, };
38 TPM2B_ENCRYPTED_SECRET encryptedSalt = { 0, };
39 TPMT_SYM_DEF symmetric = {
40 .algorithm = TPM2_ALG_NULL,
41 };
42 TSS2_TCTI_CONTEXT *tcti_ctx;
43
44 rc = Tss2_Sys_GetTctiContext (sys_ctx, &tcti_ctx);
45 if (rc != TSS2_RC_SUCCESS || tcti_ctx == NULL) {
46 LOG_ERROR("InitSysContext failed, exiting...");
47 return rc;
48 }
49
50 rc = create_auth_session (&trialPolicySession,
51 TPM2_RH_NULL,
52 0,
53 TPM2_RH_NULL,
54 0,
55 &nonceCaller,
56 &encryptedSalt,
57 TPM2_SE_TRIAL,
58 &symmetric,
59 TPM2_ALG_SHA256,
60 tcti_ctx);
61 if (rc != TSS2_RC_SUCCESS) {
62 LOG_ERROR ("create_auth_session failed with rc: 0x%x", rc);
63 return rc;
64 }
65 rc = Tss2_Sys_PolicyAuthValue (sys_ctx,
66 trialPolicySession->sessionHandle,
67 0,
68 0);
69 if (rc != TSS2_RC_SUCCESS) {
70 LOG_ERROR ("Tss2_Sys_PolicyAuthValue failed with rc: 0x%x", rc);
71 return rc;
72 }
73 rc = Tss2_Sys_PolicyGetDigest (sys_ctx,
74 trialPolicySession->sessionHandle,
75 0,
76 authPolicy,
77 0);
78 if (rc != TSS2_RC_SUCCESS) {
79 LOG_ERROR ("Tss2_Sys_PolicyGetDigest failed with rc: 0x%x", rc);
80 return rc;
81 }
82
83 rc = Tss2_Sys_FlushContext (sys_ctx,
84 trialPolicySession->sessionHandle);
85 if (rc != TSS2_RC_SUCCESS) {
86 LOG_ERROR ("Tss2_Sys_FlushContext failed with rc: 0x%x", rc);
87 return rc;
88 }
89
90 end_auth_session (trialPolicySession);
91 return rc;
92 }
93
94 TSS2_RC
95 nv_rw_with_session (
96 TSS2_SYS_CONTEXT *sys_ctx,
97 const TPM2B_DIGEST *authPolicy,
98 TPMA_NV nvAttributes,
99 TPM2_SE session_type)
100 {
101 TSS2_RC rc;
102 TPM2B_AUTH nvAuth = {
103 .size = SECRET_SIZE,
104 .buffer = SECRET_DATA,
105 };
106 SESSION *nvSession = NULL;
107 TPM2B_NAME nvName;
108 TPM2B_NONCE nonceCaller = { 0, };
109 TPM2B_MAX_NV_BUFFER nvWriteData = {
110 .size = NV_DATA_SIZE,
111 .buffer = NV_DATA,
112 };
113 TPM2B_MAX_NV_BUFFER nvReadData = { .size = TPM2B_SIZE (nvReadData), };
114 TPM2B_ENCRYPTED_SECRET encryptedSalt = { 0, };
115 TPMT_SYM_DEF symmetric = {
116 .algorithm = TPM2_ALG_NULL,
117 };
118 TSS2_TCTI_CONTEXT *tcti_ctx;
119 TSS2L_SYS_AUTH_RESPONSE nvRspAuths;
120 TSS2L_SYS_AUTH_COMMAND nvCmdAuths = {
121 .count = 1,
122 .auths= {
123 {
124 .nonce = {
125 .size = 1,
126 .buffer = { 0xa5, },
127 },
128 .sessionHandle = TPM2_RS_PW,
129 .sessionAttributes = TPMA_SESSION_CONTINUESESSION,
130 }
131 }
132 };
133 const TSS2L_SYS_AUTH_COMMAND auth_cmd_null_pwd = {
134 .count = 1,
135 .auths = {
136 {
137 .sessionHandle = TPM2_RS_PW,
138 },
139 },
140 };
141
142
143 rc = Tss2_Sys_GetTctiContext (sys_ctx, &tcti_ctx);
144 if (rc != TSS2_RC_SUCCESS || tcti_ctx == NULL) {
145 LOG_ERROR ("Failed to get TCTI from Sys context, got RC: 0x%x", rc);
146 return TSS2_SYS_RC_GENERAL_FAILURE;
147 }
148
149 rc = DefineNvIndex (sys_ctx,
150 TPM2_RH_PLATFORM,
151 &nvAuth,
152 authPolicy,
153 TPM20_INDEX_PASSWORD_TEST,
154 TPM2_ALG_SHA256,
155 nvAttributes,
156 32);
157 if (rc != TSS2_RC_SUCCESS) {
158 LOG_ERROR ("DefineNvIndex failed with RC: 0x%x", rc);
159 return rc;
160 }
161
162 /*
163 * Add index and associated authorization value to
164 * entity table. This helps when we need
165 * to calculate HMACs.
166 */
167 rc = AddEntity(TPM20_INDEX_PASSWORD_TEST, &nvAuth);
168 if (rc != TSS2_RC_SUCCESS) {
169 LOG_ERROR ("AddEntity failed with RC: 0x%x", rc);
170 return rc;
171 }
172
173 /* Get the name of the NV index. */
174 rc = tpm_handle_to_name (tcti_ctx,
175 TPM20_INDEX_PASSWORD_TEST,
176 &nvName);
177 if (rc != TSS2_RC_SUCCESS) {
178 LOG_ERROR ("tpm_handle_to_name failed with RC: 0x%x", rc);
179 return rc;
180 }
181
182 /*
183 * Start HMAC or real (non-trial) policy authorization session:
184 * it's an unbound and unsalted session, no symmetric
185 * encryption algorithm, and SHA256 is the session's
186 * hash algorithm.
187 */
188 rc = create_auth_session (&nvSession,
189 TPM2_RH_NULL,
190 0,
191 TPM2_RH_NULL,
192 0,
193 &nonceCaller,
194 &encryptedSalt,
195 session_type,
196 &symmetric,
197 TPM2_ALG_SHA256,
198 tcti_ctx);
199 if (rc != TSS2_RC_SUCCESS) {
200 LOG_ERROR ("create_auth_session failed with RC: 0x%x", rc);
201 return rc;
202 }
203
204 /* set handle in command auth */
205 nvCmdAuths.auths[0].sessionHandle = nvSession->sessionHandle;
206
207 /*
208 * Get the name of the session and save it in
209 * the nvSession structure.
210 */
211 rc = tpm_handle_to_name (tcti_ctx,
212 nvSession->sessionHandle,
213 &nvSession->name);
214 if (rc != TSS2_RC_SUCCESS) {
215 LOG_ERROR ("tpm_handle_to_name failed with RC: 0x%x", rc);
216 return rc;
217 }
218
219 /*
220 * Now setup for writing the NV index.
221 */
222 if (session_type == TPM2_SE_POLICY) {
223 rc = Tss2_Sys_PolicyAuthValue (sys_ctx,
224 nvSession->sessionHandle,
225 0,
226 0);
227 if (rc != TSS2_RC_SUCCESS) {
228 LOG_ERROR ("Tss2_Sys_PolicyAuthValue failed with RC: 0x%x", rc);
229 return rc;
230 }
231 }
232 /* First call prepare in order to create cpBuffer. */
233 rc = Tss2_Sys_NV_Write_Prepare (sys_ctx,
234 TPM20_INDEX_PASSWORD_TEST,
235 TPM20_INDEX_PASSWORD_TEST,
236 &nvWriteData,
237 0);
238 if (rc != TSS2_RC_SUCCESS) {
239 LOG_ERROR ("Tss2_Sys_NV_Write_Prepare failed with RC: 0x%x", rc);
240 return rc;
241 }
242
243 /* Roll nonces for command */
244 roll_nonces (nvSession, &nvCmdAuths.auths[0].nonce);
245
246 /*
247 * Complete command authorization area, by computing
248 * HMAC and setting it in nvCmdAuths.
249 */
250 rc = compute_command_hmac(sys_ctx,
251 TPM20_INDEX_PASSWORD_TEST,
252 TPM20_INDEX_PASSWORD_TEST,
253 TPM2_RH_NULL,
254 &nvCmdAuths);
255 if (rc != TSS2_RC_SUCCESS) {
256 LOG_ERROR ("compute_command_hmac failed with RC: 0x%x", rc);
257 return rc;
258 }
259
260 /*
261 * Finally!! Write the data to the NV index.
262 * If the command is successful, the command
263 * HMAC was correct.
264 */
265 rc = TSS2_RETRY_EXP (Tss2_Sys_NV_Write (sys_ctx,
266 TPM20_INDEX_PASSWORD_TEST,
267 TPM20_INDEX_PASSWORD_TEST,
268 &nvCmdAuths,
269 &nvWriteData,
270 0,
271 &nvRspAuths));
272 if (rc != TSS2_RC_SUCCESS) {
273 LOG_ERROR ("Tss2_Sys_NV_Write failed with RC: 0x%x", rc);
274 return rc;
275 }
276
277
278 /* Roll nonces for response */
279 roll_nonces (nvSession, &nvRspAuths.auths[0].nonce);
280
281 /*
282 * If the command was successful, check the
283 * response HMAC to make sure that the
284 * response was received correctly.
285 */
286 rc = check_response_hmac (sys_ctx,
287 &nvCmdAuths,
288 TPM20_INDEX_PASSWORD_TEST,
289 TPM20_INDEX_PASSWORD_TEST,
290 TPM2_RH_NULL,
291 &nvRspAuths);
292 if (rc != TSS2_RC_SUCCESS) {
293 LOG_ERROR ("check_response_hmac failed with RC: 0x%x", rc);
294 return rc;
295 }
296
297 if (session_type == TPM2_SE_POLICY) {
298 rc = Tss2_Sys_PolicyAuthValue (sys_ctx,
299 nvSession->sessionHandle,
300 0,
301 0);
302 if (rc != TSS2_RC_SUCCESS) {
303 LOG_ERROR ("Tss2_Sys_PolicyAuthValue failed with RC: 0x%x", rc);
304 return rc;
305 }
306 }
307 /* First call prepare in order to create cpBuffer. */
308 rc = Tss2_Sys_NV_Read_Prepare (sys_ctx,
309 TPM20_INDEX_PASSWORD_TEST,
310 TPM20_INDEX_PASSWORD_TEST,
311 NV_DATA_SIZE,
312 0);
313 if (rc != TSS2_RC_SUCCESS) {
314 LOG_ERROR ("Tss2_Sys_NV_Read_Prepare failed with RC: 0x%x", rc);
315 return rc;
316 }
317
318 roll_nonces (nvSession, &nvCmdAuths.auths[0].nonce);
319 /* End the session after next command. */
320 nvCmdAuths.auths[0].sessionAttributes &= ~TPMA_SESSION_CONTINUESESSION;
321
322 /*
323 * Complete command authorization area, by computing
324 * HMAC and setting it in nvCmdAuths.
325 */
326 rc = compute_command_hmac (sys_ctx,
327 TPM20_INDEX_PASSWORD_TEST,
328 TPM20_INDEX_PASSWORD_TEST,
329 TPM2_RH_NULL,
330 &nvCmdAuths);
331 if (rc != TSS2_RC_SUCCESS) {
332 LOG_ERROR ("compute_command_hmac failed with RC: 0x%x", rc);
333 return rc;
334 }
335
336 /*
337 * And now read the data back.
338 * If the command is successful, the command
339 * HMAC was correct.
340 */
341 rc = Tss2_Sys_NV_Read (sys_ctx,
342 TPM20_INDEX_PASSWORD_TEST,
343 TPM20_INDEX_PASSWORD_TEST,
344 &nvCmdAuths,
345 NV_DATA_SIZE,
346 0,
347 &nvReadData,
348 &nvRspAuths);
349 if (rc != TSS2_RC_SUCCESS) {
350 LOG_ERROR ("Tss2_Sys_NV_Read failed with RC: 0x%x", rc);
351 return rc;
352 }
353
354 /* Roll nonces for response */
355 roll_nonces (nvSession, &nvRspAuths.auths[0].nonce);
356
357 /*
358 * If the command was successful, check the
359 * response HMAC to make sure that the
360 * response was received correctly.
361 */
362 rc = check_response_hmac (sys_ctx,
363 &nvCmdAuths,
364 TPM20_INDEX_PASSWORD_TEST,
365 TPM20_INDEX_PASSWORD_TEST,
366 TPM2_RH_NULL,
367 &nvRspAuths);
368 if (rc != TSS2_RC_SUCCESS) {
369 LOG_ERROR ("check_response_hmac failed with RC: 0x%x", rc);
370 return rc;
371 }
372
373 /* Check that write and read data are equal. */
374 if (memcmp ((void *)&nvReadData.buffer[0],
375 (void *)&nvWriteData.buffer[0],
376 nvReadData.size))
377 {
378 LOG_ERROR ("Data read not equal to data written.");
379 return 1;
380 }
381
382 /*
383 * Now cleanup: undefine the NV index and delete
384 * the NV index's entity table entry.
385 */
386
387 /* Undefine the NV index. */
388 rc = Tss2_Sys_NV_UndefineSpace (sys_ctx,
389 TPM2_RH_PLATFORM,
390 TPM20_INDEX_PASSWORD_TEST,
391 &auth_cmd_null_pwd,
392 0);
393 if (rc != TSS2_RC_SUCCESS) {
394 LOG_ERROR ("Tss2_Sys_NV_UndefineSpace failed with RC: 0x%x", rc);
395 return rc;
396 }
397
398 /* Delete the NV index's entry in the entity table. */
399 DeleteEntity (TPM20_INDEX_PASSWORD_TEST);
400
401 /* Remove the real session from sessions table. */
402 end_auth_session (nvSession);
403 return rc;
404 }
405
406 int
407 test_invoke (TSS2_SYS_CONTEXT *sys_ctx)
408 {
409 TSS2_RC rc;
410 TPM2B_DIGEST authPolicy = { 0, };
411 TPMA_NV nvAttributes;
412
413 LOG_INFO ("HMAC session test");
414 nvAttributes = TPMA_NV_AUTHREAD | TPMA_NV_AUTHWRITE | TPMA_NV_PLATFORMCREATE;
415 rc = nv_rw_with_session (sys_ctx, &authPolicy, nvAttributes, TPM2_SE_HMAC);
416 if (rc != TSS2_RC_SUCCESS)
417 return rc;
418
419 LOG_INFO ("Policy session test");
420 authPolicy.size = TPM2B_SIZE (authPolicy);
421 rc = create_policy (sys_ctx, &authPolicy);
422 if (rc != TSS2_RC_SUCCESS)
423 return rc;
424 nvAttributes = TPMA_NV_POLICYREAD | TPMA_NV_POLICYWRITE | TPMA_NV_PLATFORMCREATE;
425 rc = nv_rw_with_session (sys_ctx, &authPolicy, nvAttributes, TPM2_SE_POLICY);
426 if (rc != TSS2_RC_SUCCESS)
427 return rc;
428
429 return TSS2_RC_SUCCESS;
430 }
1919
2020 #define LOGMODULE test
2121 #include "util/log.h"
22 #include "test-esapi.h"
2223 #include "test.h"
2324 #include "sapi-util.h"
2425
227228 &data_out,
228229 &iv_out,
229230 &rsp_auth));
231 if (rc == TPM2_RC_COMMAND_CODE) {
232 LOG_WARNING("Encrypt/Decrypt not supported by TPM");
233 rc = Tss2_Sys_NV_UndefineSpace(sapi_context,
234 TPM2_RH_OWNER,
235 nv_index,
236 &cmd_auth,
237 &rsp_auth);
238 if (rc != TSS2_RC_SUCCESS) {
239 LOG_ERROR("Tss2_Sys_NV_UndefineSpace failed: 0x%"PRIx32, rc);
240 return 99; /* fatal error */
241 }
242 rc = Tss2_Sys_FlushContext(sapi_context, object_handle);
243 if (rc != TSS2_RC_SUCCESS) {
244 LOG_ERROR("Tss2_Sys_FlushContext failed with 0x%"PRIx32, rc);
245 return 99; /* fatal error */
246 }
247 rc = Tss2_Sys_FlushContext(sapi_context, session_handle);
248 if (rc != TSS2_RC_SUCCESS) {
249 LOG_ERROR("Tss2_Sys_FlushContext failed with 0x%"PRIx32, rc);
250 return 99; /* fatal error */
251 }
252 return EXIT_SKIP;
253 }
254
230255 if (rc != TPM2_RC_SUCCESS) {
231256 LOG_ERROR("EncryptDecrypt FAILED! Response Code : 0x%x", rc);
232257 exit(1);
617617 UINT16
618618 CopySizedByteBuffer(
619619 TPM2B *dest,
620 TPM2B *src)
620 const TPM2B *src)
621621 {
622622 if (!dest)
623623 return 0;
650650 return 0;
651651 }
652652 }
653
654 TSS2_RC
655 DefineNvIndex (
656 TSS2_SYS_CONTEXT *sys_ctx,
657 TPMI_RH_PROVISION authHandle,
658 TPM2B_AUTH *auth,
659 const TPM2B_DIGEST *authPolicy,
660 TPMI_RH_NV_INDEX nvIndex,
661 TPMI_ALG_HASH nameAlg,
662 TPMA_NV attributes,
663 UINT16 size)
664 {
665 TPM2B_NV_PUBLIC publicInfo = {
666 .nvPublic = {
667 .attributes = attributes | TPMA_NV_ORDERLY,
668 .dataSize = size,
669 .nameAlg = nameAlg,
670 .nvIndex = nvIndex,
671 },
672 .size = sizeof (TPMI_RH_NV_INDEX) + sizeof (TPMI_ALG_HASH) +
673 sizeof (TPMA_NV) + sizeof (UINT16) + sizeof (UINT16),
674 };
675 CopySizedByteBuffer ((TPM2B*)&publicInfo.nvPublic.authPolicy,
676 (TPM2B*)authPolicy);
677
678 TSS2L_SYS_AUTH_RESPONSE sessionsDataOut;
679 TSS2L_SYS_AUTH_COMMAND sessionsData = {
680 .count = 1,
681 .auths = {
682 {
683 .sessionHandle = TPM2_RS_PW,
684 .sessionAttributes = 0,
685 .nonce = { .size = 0 },
686 .hmac = { .size = 0 },
687 },
688 },
689 };
690
691 return Tss2_Sys_NV_DefineSpace (sys_ctx,
692 authHandle,
693 &sessionsData,
694 auth,
695 &publicInfo,
696 &sessionsDataOut);
697 }
206206 UINT16
207207 CopySizedByteBuffer(
208208 TPM2B *dest,
209 TPM2B *src);
209 const TPM2B *src);
210
211 TSS2_RC
212 DefineNvIndex (
213 TSS2_SYS_CONTEXT *sys_ctx,
214 TPMI_RH_PROVISION authHandle,
215 TPM2B_AUTH *auth,
216 const TPM2B_DIGEST *authPolicy,
217 TPMI_RH_NV_INDEX nvIndex,
218 TPMI_ALG_HASH nameAlg,
219 TPMA_NV attributes,
220 UINT16 size);
210221
211222 #endif /* TEST_INTEGRATION_SAPI_UTIL_H */
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /***********************************************************************
2 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * Copyright (c) 2017-2018, Intel Corporation
4 *
5 * All rights reserved.
6 ***********************************************************************/
7 #include "tss2_fapi.h"
8
9 #define EXIT_SKIP 77
10 #define EXIT_ERROR 99
11
12 #define goto_error_if_not_failed(rc,msg,label) \
13 if (rc == TSS2_RC_SUCCESS) { \
14 LOG_ERROR("Error %s (%x) in Line %i: \n", msg, __LINE__, rc); \
15 goto label; }
16
17 /* This variable is set to the same value in order to allow usage in if-statements etc. */
18 extern char *fapi_profile;
19
20 #define FAPI_POLICIES TOP_SOURCEDIR "/test/data/fapi"
21
22 TSS2_RC
23 pcr_reset(FAPI_CONTEXT *context, UINT32 pcr);
24 /*
25 * This is the prototype for all integration tests in the tpm2-tss
26 * project. Integration tests are intended to exercise the combined
27 * components in the software stack. This typically means executing some
28 * SAPI function using the socket TCTI to communicate with a software
29 * TPM2 simulator.
30 * Return values:
31 * A successful test will return 0, any other value indicates failure.
32 */
33
34 int test_invoke_fapi(FAPI_CONTEXT * fapi_context);
410410
411411 end_auth_session(sessions[i]);
412412 }
413 end_auth_session(sessions[0]);
413414
414415 for( i = 0; i < ( sizeof(sessions) / sizeof (SESSION *) ); i++ )
415416 {
861862 CheckPassed( rval );
862863 }
863864
864 static TSS2_RC DefineNvIndex( TPMI_RH_PROVISION authHandle, TPMI_SH_AUTH_SESSION sessionAuthHandle, TPM2B_AUTH *auth, TPM2B_DIGEST *authPolicy,
865 TPMI_RH_NV_INDEX nvIndex, TPMI_ALG_HASH nameAlg, TPMA_NV attributes, UINT16 size )
866 {
867 TSS2_RC rval = TPM2_RC_SUCCESS;
868 TPM2B_NV_PUBLIC publicInfo;
869
870 /* Command and response session data structures. */
871 TSS2L_SYS_AUTH_RESPONSE sessionsDataOut;
872 TSS2L_SYS_AUTH_COMMAND sessionsData = { .count = 1, .auths = {{
873 .sessionHandle = TPM2_RS_PW,
874 .sessionAttributes = 0,
875 .nonce = {.size = 0},
876 .hmac = {.size = 0}}}};
877
878 attributes |= TPMA_NV_ORDERLY;
879
880 /* Init public info structure. */
881 publicInfo.size = 0;
882 publicInfo.nvPublic.attributes = attributes;
883 CopySizedByteBuffer((TPM2B *)&publicInfo.nvPublic.authPolicy, (TPM2B *)authPolicy);
884 publicInfo.nvPublic.dataSize = size;
885 publicInfo.nvPublic.nvIndex = nvIndex;
886 publicInfo.nvPublic.nameAlg = nameAlg;
887
888 /* Create the index */
889 rval = Tss2_Sys_NV_DefineSpace( sysContext, authHandle, &sessionsData, auth, &publicInfo, &sessionsDataOut );
890
891 return rval;
892 }
893
894865 typedef struct {
895866 char name[50];
896867 TSS2_RC (*buildPolicyFn )( TSS2_SYS_CONTEXT *sysContext, SESSION *trialPolicySession, TPM2B_DIGEST *policyDigest );
987958 nvAttributes |= TPMA_NV_POLICYWRITE;
988959 nvAttributes |= TPMA_NV_PLATFORMCREATE;
989960
990 rval = DefineNvIndex( TPM2_RH_PLATFORM, TPM2_RS_PW, &nvAuth, policyDigest,
961 rval = DefineNvIndex( sysContext, TPM2_RH_PLATFORM, &nvAuth, policyDigest,
991962 TPM20_INDEX_PASSWORD_TEST, TPM2_ALG_SHA256, nvAttributes, 32 );
992963 CheckPassed( rval );
993964
16981669 * Attempt write with the correct password.
16991670 * It should pass.
17001671 */
1701 rval = Tss2_Sys_NV_Write( sysContext,
1702 TPM20_INDEX_PASSWORD_TEST,
1703 TPM20_INDEX_PASSWORD_TEST,
1704 &sessionsData, &nvWriteData, 0,
1705 &sessionsDataOut );
1672 do {
1673 rval = Tss2_Sys_NV_Write( sysContext,
1674 TPM20_INDEX_PASSWORD_TEST,
1675 TPM20_INDEX_PASSWORD_TEST,
1676 &sessionsData, &nvWriteData, 0,
1677 &sessionsDataOut );
1678 } while (rval == TPM2_RC_RETRY);
17061679 /*
17071680 * Check that the function passed as
17081681 * expected. Otherwise, exit.
17341707 rval = Tss2_Sys_NV_UndefineSpace( sysContext, TPM2_RH_PLATFORM,
17351708 TPM20_INDEX_PASSWORD_TEST, &sessionsData, 0 );
17361709 CheckPassed( rval );
1737 }
1738
1739 static void SimpleHmacOrPolicyTest( bool hmacTest )
1740 {
1741 UINT32 rval, sessionCmdRval;
1742 TPM2B_AUTH nvAuth;
1743 SESSION *nvSession, *trialPolicySession;
1744 TPMA_NV nvAttributes;
1745 TPM2B_DIGEST authPolicy;
1746 TPM2B_NAME nvName;
1747 TPM2B_MAX_NV_BUFFER nvWriteData, nvReadData;
1748 UINT8 dataToWrite[] = { 0x00, 0xff, 0x55, 0xaa };
1749 char sharedSecret[] = "shared secret";
1750 int i;
1751 TPM2B_ENCRYPTED_SECRET encryptedSalt;
1752 TPMT_SYM_DEF symmetric;
1753 TPM2_SE tpmSe;
1754 char *testString;
1755 char testStringHmac[] = "HMAC";
1756 char testStringPolicy[] = "POLICY";
1757
1758 /* Response authorization area. */
1759 TSS2L_SYS_AUTH_RESPONSE nvRspAuths;
1760
1761 /* Command authorization area: one password session. */
1762 TSS2L_SYS_AUTH_COMMAND nvCmdAuths = { .count = 1, .auths= {{
1763 .sessionHandle = TPM2_RS_PW,
1764 .sessionAttributes = 0,
1765 .nonce={.size=0},
1766 .hmac={.size=0}}}};
1767
1768 TSS2_SYS_CONTEXT *simpleTestContext;
1769 TPM2B_NONCE nonceCaller;
1770
1771 nonceCaller.size = 0;
1772
1773 if( hmacTest )
1774 testString = testStringHmac;
1775 else
1776 testString = testStringPolicy;
1777
1778 LOG_INFO("SIMPLE %s SESSION TEST:", testString );
1779 /* If LOG_INFO is not compiled in, this variable is unused */
1780 (void)(testString);
1781
1782 /* Create sysContext structure. */
1783 simpleTestContext = sapi_init_from_tcti_ctx(resMgrTctiContext);
1784 if (simpleTestContext == NULL)
1785 InitSysContextFailure();
1786
1787 /* Setup the NV index's authorization value. */
1788 nvAuth.size = strlen( sharedSecret );
1789 for( i = 0; i < nvAuth.size; i++ )
1790 nvAuth.buffer[i] = sharedSecret[i];
1791
1792 /*
1793 * Create NV index.
1794 */
1795 if( hmacTest )
1796 {
1797 /* Setup the NV index's authorization value. */
1798 nvAuth.size = strlen( sharedSecret );
1799 for( i = 0; i < nvAuth.size; i++ )
1800 nvAuth.buffer[i] = sharedSecret[i];
1801
1802 /*
1803 * Set NV index's authorization policy
1804 * to zero sized policy since we won't be
1805 * using policy to authorize.
1806 */
1807
1808 authPolicy.size = 0;
1809 }
1810 else
1811 {
1812 /*
1813 * Zero sized encrypted salt, since the session
1814 * is unsalted.
1815 */
1816
1817 encryptedSalt.size = 0;
1818
1819 /* No symmetric algorithm. */
1820 symmetric.algorithm = TPM2_ALG_NULL;
1821
1822 /*
1823 * Create the NV index's authorization policy
1824 * using a trial policy session.
1825 */
1826 rval = create_auth_session(&trialPolicySession,
1827 TPM2_RH_NULL, 0, TPM2_RH_NULL, 0, &nonceCaller, &encryptedSalt,
1828 TPM2_SE_TRIAL,
1829 &symmetric, TPM2_ALG_SHA256, resMgrTctiContext );
1830 CheckPassed( rval );
1831
1832 rval = Tss2_Sys_PolicyAuthValue( simpleTestContext,
1833 trialPolicySession->sessionHandle, 0, 0 );
1834 CheckPassed( rval );
1835
1836 /* Get policy digest. */
1837 INIT_SIMPLE_TPM2B_SIZE( authPolicy );
1838 rval = Tss2_Sys_PolicyGetDigest( simpleTestContext,
1839 trialPolicySession->sessionHandle,
1840 0, &authPolicy, 0 );
1841 CheckPassed( rval );
1842
1843 /* End the trial session by flushing it. */
1844 rval = Tss2_Sys_FlushContext( simpleTestContext,
1845 trialPolicySession->sessionHandle );
1846 CheckPassed( rval );
1847
1848 /*
1849 * And remove the trial policy session from
1850 * sessions table.
1851 */
1852 end_auth_session( trialPolicySession );
1853 }
1854
1855 /*
1856 * Now set the NV index's attributes:
1857 * policyRead, authWrite, and platormCreate.
1858 */
1859 *(UINT32 *)( &nvAttributes ) = 0;
1860 if( hmacTest )
1861 {
1862 nvAttributes |= TPMA_NV_AUTHREAD;
1863 nvAttributes |= TPMA_NV_AUTHWRITE;
1864 }
1865 else
1866 {
1867 nvAttributes |= TPMA_NV_POLICYREAD;
1868 nvAttributes |= TPMA_NV_POLICYWRITE;
1869 }
1870 nvAttributes |= TPMA_NV_PLATFORMCREATE;
1871
1872 /* Create the NV index. */
1873 rval = DefineNvIndex( TPM2_RH_PLATFORM, TPM2_RS_PW,
1874 &nvAuth, &authPolicy, TPM20_INDEX_PASSWORD_TEST,
1875 TPM2_ALG_SHA256, nvAttributes, 32 );
1876 CheckPassed( rval );
1877
1878 /*
1879 * Add index and associated authorization value to
1880 * entity table. This helps when we need
1881 * to calculate HMACs.
1882 */
1883 rval = AddEntity(TPM20_INDEX_PASSWORD_TEST, &nvAuth);
1884 CheckPassed(rval);
1885
1886 /* Get the name of the NV index. */
1887 rval = tpm_handle_to_name(
1888 resMgrTctiContext,
1889 TPM20_INDEX_PASSWORD_TEST,
1890 &nvName);
1891 CheckPassed( rval );
1892
1893
1894 /*
1895 * Start HMAC or real (non-trial) policy authorization session:
1896 * it's an unbound and unsalted session, no symmetric
1897 * encryption algorithm, and SHA256 is the session's
1898 * hash algorithm.
1899 */
1900
1901 /*
1902 * Zero sized encrypted salt, since the session
1903 * is unsalted.
1904 */
1905 encryptedSalt.size = 0;
1906
1907 /* No symmetric algorithm. */
1908 symmetric.algorithm = TPM2_ALG_NULL;
1909
1910 /*
1911 * Create the session, hmac or policy depending
1912 * on hmacTest.
1913 * Session state (session handle, nonces, etc.) gets
1914 * saved into nvSession structure for later use.
1915 */
1916 if( hmacTest )
1917 tpmSe = TPM2_SE_HMAC;
1918 else
1919 tpmSe = TPM2_SE_POLICY;
1920
1921 rval = create_auth_session(&nvSession, TPM2_RH_NULL,
1922 0, TPM2_RH_NULL, 0, &nonceCaller, &encryptedSalt, tpmSe,
1923 &symmetric, TPM2_ALG_SHA256, resMgrTctiContext );
1924 CheckPassed( rval );
1925
1926 /*
1927 * Get the name of the session and save it in
1928 * the nvSession structure.
1929 */
1930 rval = tpm_handle_to_name(
1931 resMgrTctiContext,
1932 nvSession->sessionHandle,
1933 &(nvSession->name) );
1934 CheckPassed( rval );
1935
1936 /* Initialize NV write data. */
1937 nvWriteData.size = sizeof( dataToWrite );
1938 for( i = 0; i < nvWriteData.size; i++ )
1939 {
1940 nvWriteData.buffer[i] = dataToWrite[i];
1941 }
1942
1943 /*
1944 * Now setup for writing the NV index.
1945 */
1946 if( !hmacTest )
1947 {
1948 /* Send policy command. */
1949 rval = Tss2_Sys_PolicyAuthValue( simpleTestContext,
1950 nvSession->sessionHandle, 0, 0 );
1951 CheckPassed( rval );
1952 }
1953
1954 /* First call prepare in order to create cpBuffer. */
1955 rval = Tss2_Sys_NV_Write_Prepare( simpleTestContext,
1956 TPM20_INDEX_PASSWORD_TEST,
1957 TPM20_INDEX_PASSWORD_TEST, &nvWriteData, 0 );
1958 CheckPassed( rval );
1959
1960 /* Configure command authorization area, except for HMAC. */
1961 nvCmdAuths.auths[0].sessionHandle = nvSession->sessionHandle;
1962 nvCmdAuths.auths[0].nonce.size = 1;
1963 nvCmdAuths.auths[0].nonce.buffer[0] = 0xa5;
1964 nvCmdAuths.auths[0].sessionAttributes = 0;
1965 nvCmdAuths.auths[0].sessionAttributes |= TPMA_SESSION_CONTINUESESSION;
1966
1967 /* Roll nonces for command */
1968 roll_nonces(nvSession, &nvCmdAuths.auths[0].nonce );
1969
1970 /*
1971 * Complete command authorization area, by computing
1972 * HMAC and setting it in nvCmdAuths.
1973 */
1974 rval = compute_command_hmac(
1975 simpleTestContext,
1976 TPM20_INDEX_PASSWORD_TEST,
1977 TPM20_INDEX_PASSWORD_TEST,
1978 TPM2_RH_NULL,
1979 &nvCmdAuths);
1980 CheckPassed(rval);
1981
1982 /*
1983 * Finally!! Write the data to the NV index.
1984 * If the command is successful, the command
1985 * HMAC was correct.
1986 */
1987 sessionCmdRval = Tss2_Sys_NV_Write(simpleTestContext,
1988 TPM20_INDEX_PASSWORD_TEST,
1989 TPM20_INDEX_PASSWORD_TEST,
1990 &nvCmdAuths, &nvWriteData, 0, &nvRspAuths);
1991 CheckPassed(sessionCmdRval);
1992
1993 /* Roll nonces for response */
1994 roll_nonces(nvSession, &nvRspAuths.auths[0].nonce );
1995
1996 if (sessionCmdRval == TPM2_RC_SUCCESS) {
1997 /*
1998 * If the command was successful, check the
1999 * response HMAC to make sure that the
2000 * response was received correctly.
2001 */
2002 rval = check_response_hmac(
2003 simpleTestContext,
2004 &nvCmdAuths,
2005 TPM20_INDEX_PASSWORD_TEST,
2006 TPM20_INDEX_PASSWORD_TEST,
2007 TPM2_RH_NULL,
2008 &nvRspAuths);
2009 CheckPassed(rval);
2010 }
2011
2012 if( !hmacTest )
2013 {
2014 /* Send policy command. */
2015 rval = Tss2_Sys_PolicyAuthValue( simpleTestContext,
2016 nvSession->sessionHandle, 0, 0 );
2017 CheckPassed( rval );
2018 }
2019
2020 /* First call prepare in order to create cpBuffer. */
2021 rval = Tss2_Sys_NV_Read_Prepare( simpleTestContext,
2022 TPM20_INDEX_PASSWORD_TEST,
2023 TPM20_INDEX_PASSWORD_TEST,
2024 sizeof( dataToWrite ), 0 );
2025 CheckPassed( rval );
2026
2027 /* Roll nonces for command */
2028 roll_nonces(nvSession, &nvCmdAuths.auths[0].nonce );
2029
2030 /* End the session after next command. */
2031 nvCmdAuths.auths[0].sessionAttributes &= ~TPMA_SESSION_CONTINUESESSION;
2032
2033 /*
2034 * Complete command authorization area, by computing
2035 * HMAC and setting it in nvCmdAuths.
2036 */
2037 rval = compute_command_hmac(
2038 simpleTestContext,
2039 TPM20_INDEX_PASSWORD_TEST,
2040 TPM20_INDEX_PASSWORD_TEST,
2041 TPM2_RH_NULL,
2042 &nvCmdAuths);
2043 CheckPassed(rval);
2044
2045 /*
2046 * And now read the data back.
2047 * If the command is successful, the command
2048 * HMAC was correct.
2049 */
2050 INIT_SIMPLE_TPM2B_SIZE( nvReadData );
2051 sessionCmdRval = Tss2_Sys_NV_Read( simpleTestContext,
2052 TPM20_INDEX_PASSWORD_TEST,
2053 TPM20_INDEX_PASSWORD_TEST,
2054 &nvCmdAuths, sizeof( dataToWrite ), 0,
2055 &nvReadData, &nvRspAuths );
2056 CheckPassed( sessionCmdRval );
2057
2058 /* Roll nonces for response */
2059 roll_nonces(nvSession, &nvRspAuths.auths[0].nonce );
2060
2061 if (sessionCmdRval == TPM2_RC_SUCCESS) {
2062 /*
2063 * If the command was successful, check the
2064 * response HMAC to make sure that the
2065 * response was received correctly.
2066 */
2067 rval = check_response_hmac(
2068 simpleTestContext,
2069 &nvCmdAuths,
2070 TPM20_INDEX_PASSWORD_TEST,
2071 TPM20_INDEX_PASSWORD_TEST,
2072 TPM2_RH_NULL,
2073 &nvRspAuths);
2074 CheckPassed(rval);
2075 }
2076
2077 /* Check that write and read data are equal. */
2078 if( memcmp( (void *)&nvReadData.buffer[0],
2079 (void *)&nvWriteData.buffer[0], nvReadData.size ) )
2080 {
2081 LOG_ERROR("ERROR!! read data not equal to written data" );
2082 Cleanup();
2083 }
2084
2085 /*
2086 * Now cleanup: undefine the NV index and delete
2087 * the NV index's entity table entry.
2088 */
2089
2090 /* Setup authorization for undefining the NV index. */
2091 nvCmdAuths.auths[0].sessionHandle = TPM2_RS_PW;
2092 nvCmdAuths.auths[0].nonce.size = 0;
2093 nvCmdAuths.auths[0].hmac.size = 0;
2094
2095 /* Undefine the NV index. */
2096 rval = Tss2_Sys_NV_UndefineSpace( simpleTestContext,
2097 TPM2_RH_PLATFORM, TPM20_INDEX_PASSWORD_TEST,
2098 &nvCmdAuths, 0 );
2099 CheckPassed( rval );
2100
2101 /* Delete the NV index's entry in the entity table. */
2102 DeleteEntity(TPM20_INDEX_PASSWORD_TEST);
2103
2104 /* Remove the real session from sessions table. */
2105 end_auth_session( nvSession );
2106
2107 sapi_teardown(simpleTestContext);
21081710 }
21091711
21101712 static void GetSetDecryptParamTests()
22181820 }
22191821
22201822 /* Test for insufficient size. */
1823 /* Create a buffer that is too large */
1824 size_t testBufferSize = TPM2_MAX_COMMAND_SIZE -
1825 BE_TO_HOST_32(((TPM20_Header_In *)(((_TSS2_SYS_CONTEXT_BLOB *)decryptParamTestSysContext)->cmdBuffer))->commandSize) + 1;
1826 UINT8 testBuffer [testBufferSize];
1827 memset(testBuffer, 0, testBufferSize);
1828 memcpy(testBuffer, nvWriteData.buffer, nvWriteData.size);
1829
22211830 rval = Tss2_Sys_GetCpBuffer(decryptParamTestSysContext, &cpBufferUsedSize2, &cpBuffer2);
22221831 CheckPassed(rval);
2223 nvWriteData.size = TPM2_MAX_COMMAND_SIZE -
2224 BE_TO_HOST_32(((TPM20_Header_In *)(((_TSS2_SYS_CONTEXT_BLOB *)decryptParamTestSysContext)->cmdBuffer))->commandSize) + 1;
2225
2226 rval = Tss2_Sys_SetDecryptParam(decryptParamTestSysContext, nvWriteData.size, nvWriteData.buffer);
1832 rval = Tss2_Sys_SetDecryptParam(decryptParamTestSysContext, testBufferSize,
1833 testBuffer);
22271834 CheckFailed(rval, TSS2_SYS_RC_INSUFFICIENT_CONTEXT);
22281835
22291836 /*
22301837 * Test that one less will work.
22311838 * This tests that we're checking the correct corner case.
22321839 */
2233 nvWriteData.size -= 1;
2234 rval = Tss2_Sys_SetDecryptParam(decryptParamTestSysContext, nvWriteData.size, nvWriteData.buffer);
1840 testBufferSize -= 1;
1841 rval = Tss2_Sys_SetDecryptParam(decryptParamTestSysContext, testBufferSize,
1842 testBuffer);
22351843 CheckPassed(rval);
22361844
22371845 rval = Tss2_Sys_NV_Write_Prepare( decryptParamTestSysContext, TPM20_INDEX_PASSWORD_TEST,
23731981 nvAttributes |= TPMA_NV_AUTHWRITE;
23741982 nvAttributes |= TPMA_NV_PLATFORMCREATE;
23751983
2376 rval = DefineNvIndex( TPM2_RH_PLATFORM, TPM2_RS_PW, &nvAuth, &authPolicy,
1984 rval = DefineNvIndex( sysContext, TPM2_RH_PLATFORM, &nvAuth, &authPolicy,
23771985 TPM20_INDEX_PASSWORD_TEST, TPM2_ALG_SHA1, nvAttributes, 32 );
23781986 CheckPassed( rval ); /* #4 */
23791987
25602168 TestDictionaryAttackLockReset();
25612169 TestHierarchyControl();
25622170 GetSetEncryptParamTests();
2563 SimpleHmacOrPolicyTest( true );
25642171 TestTpmGetCapability();
25652172 TestPcrExtend();
25662173 TestHash();
227227 size_t buffer_size = sizeof(buffer);
228228 uint32_t value = 0xdeadbeef;
229229 uint32_t value2 = 0x11223344;
230 uint32_t *ptr;
230 uint32_t val;
231231 TSS2_RC rc;
232232
233233 rc = Tss2_MU_TPM2B_DIGEST_Unmarshal(buffer, buffer_size, &offset, &dgst);
234234 assert_int_equal (rc, TSS2_RC_SUCCESS);
235235 assert_int_equal (dgst.size, 4);
236 ptr = (uint32_t *)dgst.buffer;
237 assert_int_equal (le32toh(*ptr), value);
236 memcpy(&val, dgst.buffer, sizeof(val));
237 assert_int_equal (le32toh(val), value);
238238 assert_int_equal (offset, 6);
239239
240240 rc = Tss2_MU_TPM2B_ECC_POINT_Unmarshal(buffer, buffer_size, &offset, &point);
241241 assert_int_equal (rc, TSS2_RC_SUCCESS);
242242 assert_int_equal (point.point.x.size, 4);
243 ptr = (uint32_t *)point.point.x.buffer;
244 assert_int_equal (le32toh(*ptr), value);
243 memcpy(&val, point.point.x.buffer, sizeof(val));
244 assert_int_equal (le32toh(val), value);
245245 assert_int_equal (point.point.y.size, 4);
246 ptr = (uint32_t *)point.point.y.buffer;
247 assert_int_equal (le32toh(*ptr), value2);
246 memcpy(&val, point.point.y.buffer, sizeof(val));
247 assert_int_equal (le32toh(val), value2);
248248 assert_int_equal (offset, 20);
249249 }
250250
267267 uint32_t value = 0xdeadbeef;
268268 uint64_t value2 = 0xdeadbeefdeadbeefULL;
269269 uint32_t value3 = 0x11223344;
270 uint32_t *ptr;
271 uint64_t *ptr2;
270 uint32_t val;
271 uint64_t val2;
272272 TSS2_RC rc;
273273
274274 rc = Tss2_MU_TPM2B_DIGEST_Unmarshal(buffer, buffer_size, &offset, &dgst);
275275 assert_int_equal (rc, TSS2_RC_SUCCESS);
276276 assert_int_equal (dgst.size, 4);
277 ptr = (uint32_t *)dgst.buffer;
278 assert_int_equal (le32toh(*ptr), value);
277 memcpy(&val, dgst.buffer, sizeof(val));
278 assert_int_equal (le32toh(val), value);
279279 assert_int_equal (offset, 12);
280280
281281 rc = Tss2_MU_TPM2B_ECC_POINT_Unmarshal(buffer, buffer_size, &offset, &point);
282282 assert_int_equal (rc, TSS2_RC_SUCCESS);
283283 assert_int_equal (point.point.x.size, 8);
284 ptr2 = (uint64_t *)point.point.x.buffer;
285 assert_int_equal (le64toh(*ptr2), value2);
284 memcpy(&val2, point.point.x.buffer, sizeof(val2));
285 assert_int_equal (le64toh(val2), value2);
286286 assert_int_equal (point.point.y.size, 4);
287 ptr = (uint32_t *)point.point.y.buffer;
288 assert_int_equal (le32toh(*ptr), value3);
287 memcpy(&val, point.point.y.buffer, sizeof(val));
288 assert_int_equal (le32toh(val), value3);
289289 assert_int_equal (offset, 30);
290290 }
291291
249249 Esys_Free(buffer);
250250 }
251251
252
252 static void
253 check_get_sys_context(void **state)
254 {
255 ESYS_CONTEXT *ctx;
256 TSS2_TCTI_CONTEXT_COMMON_V1 tcti = {0};
257 TSS2_SYS_CONTEXT *sys_ctx = NULL;
258 TSS2_RC rc;
259
260 rc = Esys_GetSysContext(NULL, NULL);
261 assert_int_equal(rc, TSS2_ESYS_RC_BAD_REFERENCE);
262
263 tcti.version = 1;
264 tcti.transmit = (void*) 0xdeadbeef;
265 tcti.receive = (void*) 0xdeadbeef;
266
267 rc = Esys_Initialize(&ctx, (TSS2_TCTI_CONTEXT *) &tcti, NULL);
268 assert_int_equal(rc, TSS2_RC_SUCCESS);
269
270 rc = Esys_GetSysContext(ctx, &sys_ctx);
271 assert_ptr_not_equal(sys_ctx, NULL);
272 assert_int_equal(rc, TSS2_RC_SUCCESS);
273
274 Esys_Finalize(&ctx);
275 }
253276
254277 int
255278 main(int argc, char *argv[])
261284 cmocka_unit_test(check_pk_encrypt),
262285 cmocka_unit_test(check_aes_encrypt),
263286 cmocka_unit_test(check_free),
287 cmocka_unit_test(check_get_sys_context),
264288 };
265289 return cmocka_run_group_tests(tests, NULL, NULL);
266290 }
5555 }
5656
5757 void
58 tctildr_finalize_data (void **data)
58 __wrap_Tss2_TctiLdr_Finalize (TSS2_TCTI_CONTEXT **tcti)
5959 {
60 return;
60 free(*tcti);
61 *tcti = NULL;
6162 }
6263
6364 static void
199199 return TSS2_RC_SUCCESS;
200200
201201 LOG_ERROR("Expected 2 receives before the next transmit, but %" PRIu32
202 "receives occured.", tcti->count);
202 "receives occurred.", tcti->count);
203203 return TSS2_TCTI_RC_GENERAL_FAILURE;
204204 }
205205
225225 TSS2_TCTI_CONTEXT_TRYAGAINERROR *tcti = tcti_tryagainerror_cast(tctiContext);
226226 if (tcti->count != 2) {
227227 LOG_ERROR("Expected 2 receives before the next transmit, but %" PRIu32
228 "receives occured.", tcti->count);
228 "receives occurred.", tcti->count);
229229 exit(1);
230230 }
231231 }
0 /* SPDX-License-Identifier: BSD-2-Clause */
1 /*******************************************************************************
2 * Copyright 2018, Fraunhofer SIT sponsored by Infineon Technologies AG
3 * All rights reserved.
4 ******************************************************************************/
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdarg.h>
11 #include <inttypes.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <json-c/json_util.h>
16 #include <json-c/json_tokener.h>
17
18 #include <setjmp.h>
19 #include <cmocka.h>
20
21 #include "tss2_fapi.h"
22 #include "tpm_json_serialize.h"
23 #include "tpm_json_deserialize.h"
24 #include "ifapi_json_serialize.h"
25 #include "ifapi_json_deserialize.h"
26 #include "fapi_policy.h"
27
28 #include "util/aux_util.h"
29
30 #define LOGMODULE tests
31 #include "util/log.h"
32
33 /* 3 copies from ifapi_helpers.c */
34 static void
35 cleanup_policy_element(TPMT_POLICYELEMENT *policy)
36 {
37 switch (policy->type) {
38 case POLICYSECRET:
39 SAFE_FREE(policy->element.PolicySecret.objectPath);
40 break;
41 case POLICYAUTHORIZE:
42 SAFE_FREE(policy->element.PolicyAuthorize.keyPath);
43 SAFE_FREE(policy->element.PolicyAuthorize.keyPEM);
44 break;
45 case POLICYAUTHORIZENV:
46 SAFE_FREE( policy->element.PolicyAuthorizeNv.nvPath);
47 SAFE_FREE( policy->element.PolicyAuthorizeNv.policy_buffer);
48 break;
49 case POLICYSIGNED:
50 SAFE_FREE(policy->element.PolicySigned.keyPath);
51 SAFE_FREE(policy->element.PolicySigned.keyPEM);
52 break;
53 case POLICYPCR:
54 SAFE_FREE(policy->element.PolicyPCR.pcrs);
55 break;
56 case POLICYNV:
57 SAFE_FREE(policy->element.PolicyNV.nvPath);
58 break;
59 case POLICYDUPLICATIONSELECT:
60 SAFE_FREE(policy->element.PolicyDuplicationSelect.newParentPath);
61 break;
62 }
63 }
64
65 static void cleanup_policy_elements(TPML_POLICYELEMENTS *policy)
66 {
67 size_t i, j;
68 if (policy != NULL) {
69 for (i = 0; i < policy->count; i++) {
70 if (policy->elements[i].type == POLICYOR) {
71 /* Policy with sub policies */
72 TPML_POLICYBRANCHES *branches = policy->elements[i].element.PolicyOr.branches;
73 for (j = 0; j < branches->count; j++) {
74 SAFE_FREE(branches->authorizations[j].name);
75 SAFE_FREE(branches->authorizations[j].description);
76 cleanup_policy_elements(branches->authorizations[j].policy);
77 }
78 SAFE_FREE(branches);
79 } else {
80 cleanup_policy_element(&policy->elements[i]);
81 }
82 }
83 SAFE_FREE(policy);
84 }
85 }
86
87 /** Free memory allocated during deserialization of policy.
88 *
89 * The object will not be freed (might be declared on the stack).
90 *
91 * @param[in] object The policy to be cleaned up.
92 *
93 */
94 static void ifapi_cleanup_policy(TPMS_POLICY *policy)
95 {
96 if (policy) {
97 SAFE_FREE(policy->description);
98 SAFE_FREE(policy->policyAuthorizations);
99 cleanup_policy_elements(policy->policy);
100 }
101 }
102
103 char * normalize(const char *string) {
104 char *string2 = malloc(strlen(string)+1);
105 int i;
106 int j = 0;
107 for(i = 0; string[i] != '\0'; i++) {
108 if ((string[i] != '\n' && string[i] != ' ')) {
109 string2[j] = string[i];
110 j += 1;
111 }
112 }
113 string2[j] = '\0';
114 return string2;
115 }
116
117 #define CHECK_ERROR(TYPE, SRC, RC) \
118 { \
119 TYPE out; \
120 TSS2_RC rc; \
121 json_object *jso = json_tokener_parse((SRC)); \
122 assert_non_null(jso); \
123 rc = ifapi_json_ ## TYPE ## _deserialize (jso, &out); \
124 assert_int_equal (rc, RC); \
125 json_object_put(jso); \
126 }
127
128
129
130 #define CHECK_JSON2(TYPE, SRC, DST, PSERIALIZE) \
131 { \
132 TYPE out; \
133 TSS2_RC rc; \
134 json_object *jso = json_tokener_parse((SRC)); \
135 if (!jso) fprintf(stderr, "JSON parsing failed\n"); \
136 assert_non_null(jso); \
137 rc = ifapi_json_ ## TYPE ## _deserialize (jso, &out); \
138 if (rc) fprintf(stderr, "Deserialization failed\n"); \
139 assert_int_equal (rc, TSS2_RC_SUCCESS); \
140 json_object_put(jso); \
141 jso = NULL; \
142 rc = ifapi_json_ ## TYPE ## _serialize (PSERIALIZE, &jso); \
143 assert_int_equal (rc, TSS2_RC_SUCCESS); \
144 assert_non_null(jso); \
145 const char *jso_string = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY); \
146 assert_non_null(jso_string); \
147 char *string1 = normalize(jso_string); \
148 char *string2 = normalize(DST); \
149 assert_string_equal(string1, string2); \
150 json_object_put(jso); \
151 free(string1); \
152 free(string2); \
153 }
154
155 #define CHECK_JSON(TYPE, SRC, DST) \
156 CHECK_JSON2(TYPE, SRC, DST, &out)
157
158 #define CHECK_JSON_SIMPLE(TYPE, SRC, DST) \
159 CHECK_JSON2(TYPE, SRC, DST, out)
160
161 #define CHECK_JSON_TO_BIN(TYPE, SRC, DST) \
162 { \
163 TYPE out; \
164 TSS2_RC rc; \
165 TYPE expected = DST; \
166 json_object *jso = json_tokener_parse((SRC)); \
167 assert_non_null(jso); \
168 rc = ifapi_json_ ## TYPE ## _deserialize (jso, &out); \
169 assert_int_equal (rc, TSS2_RC_SUCCESS); \
170 json_object_put(jso); \
171 assert_true(out == expected); \
172 }
173
174 #define CHECK_BIN2(TYPE, BIN, PSERIALIZE) \
175 TYPE BIN ## 2; \
176 { \
177 char *jso_string1, *jso_string2; \
178 json_object *jso = NULL; \
179 TSS2_RC rc = ifapi_json_ ## TYPE ## _serialize (PSERIALIZE, &jso); \
180 jso_string1 = strdup(json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY)); \
181 assert_int_equal (rc, TSS2_RC_SUCCESS); \
182 rc = ifapi_json_ ## TYPE ## _deserialize (jso, &BIN ## 2); \
183 assert_int_equal (rc, TSS2_RC_SUCCESS); \
184 json_object_put(jso); \
185 jso = NULL; \
186 rc = ifapi_json_ ## TYPE ## _serialize (PSERIALIZE ## 2, &jso); \
187 jso_string2 = strdup(json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY)); \
188 assert_int_equal (rc, TSS2_RC_SUCCESS); \
189 if (strcmp(jso_string1, jso_string2)) { \
190 fprintf(stderr,"\n jso: %s\n", jso_string1); \
191 fprintf(stderr,"\n jso: %s\n", jso_string2); \
192 } \
193 assert_string_equal(jso_string1, jso_string2); \
194 json_object_put(jso); \
195 free(jso_string1); \
196 free(jso_string2); \
197 }
198
199 #define CHECK_BIN(TYPE, BIN) \
200 CHECK_BIN2(TYPE, BIN, &BIN)
201
202 #define CHECK_BIN_SIMPLE(TYPE, BIN) \
203 CHECK_BIN2(TYPE, BIN, BIN)
204
205 static void
206 check_bin(void **state)
207 {
208 TPM2B_PUBLIC inPublicAES = {
209 .size = 0,
210 .publicArea = {
211 .type = TPM2_ALG_SYMCIPHER,
212 .nameAlg = TPM2_ALG_SHA256,
213 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
214 TPMA_OBJECT_SIGN_ENCRYPT |
215 TPMA_OBJECT_DECRYPT),
216
217 .authPolicy = {
218 .size = 0,
219 },
220 .parameters.symDetail = {
221 .sym = {
222 .algorithm = TPM2_ALG_AES,
223 .keyBits = {.aes = 128},
224 .mode = {.aes = TPM2_ALG_CFB}}
225 },
226 .unique.sym = {
227 .size = 0,
228 .buffer = {}
229 }
230 }
231 };
232
233 CHECK_BIN(TPM2B_PUBLIC, inPublicAES);
234
235 TPM2B_PUBLIC inPublicECC = {
236 .size = 0,
237 .publicArea = {
238 .type = TPM2_ALG_ECC,
239 .nameAlg = TPM2_ALG_SHA1,
240 .objectAttributes = (
241 TPMA_OBJECT_USERWITHAUTH |
242 TPMA_OBJECT_RESTRICTED |
243 TPMA_OBJECT_SIGN_ENCRYPT |
244 TPMA_OBJECT_FIXEDTPM |
245 TPMA_OBJECT_FIXEDPARENT |
246 TPMA_OBJECT_SENSITIVEDATAORIGIN
247 ),
248 .authPolicy = {
249 .size = 0,
250 },
251
252 .parameters.eccDetail = {
253 .symmetric = {
254 .algorithm = TPM2_ALG_NULL,
255 .keyBits.aes = 128,
256 .mode.aes = TPM2_ALG_ECB,
257 },
258 .scheme = {
259 .scheme = TPM2_ALG_ECDAA,
260 .details = { .ecdaa = { .hashAlg = TPM2_ALG_SHA256 }},
261 },
262 .curveID = TPM2_ECC_BN_P256,
263 .kdf = { .scheme = TPM2_ALG_NULL, .details = {} }
264 },
265 /*
266 .parameters.asymDetail.symmetric.algorithm = TPM2_ALG_NULL,
267 */
268 .unique.ecc = {
269 .x = { .size = 0, .buffer = {} } ,
270 .y = { .size = 0, .buffer = {} } ,
271 },
272 },
273 };
274
275
276 CHECK_BIN(TPM2B_PUBLIC, inPublicECC);
277
278 TPM2B_PUBLIC inPublicRSA2 = {
279 .size = 0,
280 .publicArea = {
281 .type = TPM2_ALG_RSA,
282 .nameAlg = TPM2_ALG_SHA1,
283 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
284 TPMA_OBJECT_SIGN_ENCRYPT |
285 TPMA_OBJECT_FIXEDTPM |
286 TPMA_OBJECT_FIXEDPARENT |
287 TPMA_OBJECT_SENSITIVEDATAORIGIN),
288 .authPolicy = {
289 .size = 0,
290 },
291 .parameters.rsaDetail = {
292 .symmetric = {
293 .algorithm = TPM2_ALG_NULL,
294 .keyBits.aes = 128,
295 .mode.aes = TPM2_ALG_CFB},
296 .scheme = {
297 .scheme = TPM2_ALG_RSAPSS,
298 .details = {
299 .rsapss = { .hashAlg = TPM2_ALG_SHA1 }
300 }
301 },
302 .keyBits = 2048,
303 .exponent = 0,
304 },
305 .unique.rsa = {
306 .size = 0,
307 .buffer = {},
308 },
309 },
310 };
311
312 CHECK_BIN(TPM2B_PUBLIC, inPublicRSA2);
313
314 TPMT_SIG_SCHEME ecc_scheme = { .scheme = TPM2_ALG_ECDSA, .details.ecdsa = TPM2_ALG_SHA1 };
315
316 CHECK_BIN(TPMT_SIG_SCHEME, ecc_scheme);
317
318 TPMT_SIG_SCHEME rsa_scheme = { .scheme = TPM2_ALG_NULL };
319
320 CHECK_BIN(TPMT_SIG_SCHEME, rsa_scheme);
321
322 TPMA_NV testNV = 0xffffff0f ;
323
324 CHECK_BIN_SIMPLE(TPMA_NV, testNV);
325
326 TPML_PCR_SELECTION pcr_selection = {
327 .count = 3,
328 .pcrSelections = {
329 {
330 .hash = TPM2_ALG_SHA1,
331 .sizeofSelect = 3,
332 .pcrSelect = { 01, 00, 03 }},
333 {
334 .hash = TPM2_ALG_SHA256,
335 .sizeofSelect = 3,
336 .pcrSelect = { 01 ,00 ,03 }},
337 {
338 .hash = TPM2_ALG_SHA384,
339 .sizeofSelect = 3,
340 .pcrSelect = { 02, 00, 02 }}
341 }
342 };
343
344 CHECK_BIN(TPML_PCR_SELECTION, pcr_selection);
345
346 IFAPI_IMA_EVENT imaEvent = {
347 .eventData = {
348 .size = 0,
349 .buffer = { 0 }
350 },
351 .eventName = "Event"
352 };
353
354 CHECK_BIN(IFAPI_IMA_EVENT, imaEvent);
355 free(imaEvent2.eventName);
356 }
357
358 static void
359 check_policy_bin(void **state)
360 {
361 TPMS_PCRVALUE pcr_value;
362 TPML_PCRVALUES *pcr_value_list;
363 TPML_POLICYBRANCHES *or_branch_list;
364 TPMS_POLICYPCR pcr_policy;
365 TPMT_POLICYELEMENT policy_element0;
366 TPMT_POLICYELEMENT policy_element1;
367 TPMT_POLICYELEMENT policy_element_or;
368 TPML_POLICYELEMENTS *policy_elements_or;
369 TPML_POLICYELEMENTS *policy_elements0;
370 TPML_POLICYELEMENTS *policy_elements1;
371 TPMS_POLICY policy;
372 TPMS_POLICYBRANCH branch0;
373 TPMS_POLICYBRANCH branch1;
374
375 pcr_value.pcr = 16;
376 pcr_value.hashAlg = TPM2_ALG_SHA1;
377 memset(&pcr_value.digest, 0, sizeof(TPMU_HA));
378 memset(&pcr_policy, 0, sizeof(TPMS_POLICYPCR));
379 pcr_value_list = calloc(1, sizeof(TPML_PCRVALUES) + sizeof(TPMS_PCRVALUE));
380 if (pcr_value_list == NULL) {
381 LOG_ERROR("%s", "Out of memory.");
382 return;
383 }
384 pcr_value_list->count = 1;
385 pcr_value_list->pcrs[0] = pcr_value;
386 pcr_policy.pcrs = pcr_value_list;
387 memset(&policy_element0, 0, sizeof(TPMT_POLICYELEMENT));
388 policy_element0.element.PolicyPCR = pcr_policy;
389 policy_element0.type = POLICYPCR;
390 memset(&policy_element1, 0, sizeof(TPMT_POLICYELEMENT));
391 policy_element1.element.PolicyPCR = pcr_policy;
392 policy_element1.type = POLICYPCR;
393 policy_elements0 = calloc(1, sizeof(TPML_POLICYELEMENTS) + sizeof(TPMT_POLICYELEMENT));
394 if (policy_elements0 == NULL) {
395 LOG_ERROR("%s", "Out of memory.");
396 if (pcr_policy.pcrs){
397 free(pcr_policy.pcrs);
398 }
399 return;
400 }
401 policy_elements0->count = 1;
402 policy_elements0->elements[0] = policy_element0;
403 policy.policy = policy_elements0;
404 policy.description = "hareness description";
405 policy.policyAuthorizations = NULL;
406 memset(&policy.policyDigests, 0, sizeof(TPML_DIGEST_VALUES));
407
408 //CHECK_BIN(TPMS_POLICY, policy);
409 {
410 char *jso_string1, *jso_string2;
411 json_object *jso = NULL;
412 TSS2_RC rc = ifapi_json_TPMS_POLICY_serialize (&policy, &jso);
413 jso_string1 = strdup(json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY));
414 assert_int_equal (rc, TSS2_RC_SUCCESS);
415 rc = ifapi_json_TPMS_POLICY_deserialize (jso, &policy);
416 assert_int_equal (rc, TSS2_RC_SUCCESS);
417 json_object_put(jso);
418 jso = NULL;
419 rc = ifapi_json_TPMS_POLICY_serialize (&policy, &jso);
420 jso_string2 = strdup(json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY));
421 assert_int_equal (rc, TSS2_RC_SUCCESS);
422 if (strcmp(jso_string1, jso_string2)) {
423 fprintf(stderr,"\n jso: %s\n", jso_string1);
424 fprintf(stderr,"\n jso: %s\n", jso_string2);
425 }
426 assert_string_equal(jso_string1, jso_string2);
427 json_object_put(jso);
428 free(jso_string1);
429 free(jso_string2);
430 }
431 ifapi_cleanup_policy(&policy);
432
433 or_branch_list = calloc(2, sizeof(TPML_POLICYBRANCHES) + (2 * sizeof(TPMS_POLICYBRANCH)));
434 if (or_branch_list == NULL) {
435 LOG_ERROR("%s", "Out of memory.");
436 return;
437 }
438 or_branch_list->count = 2;
439
440 policy_elements1 = calloc(1, sizeof(TPML_POLICYELEMENTS) + sizeof(TPMT_POLICYELEMENT));
441 if (policy_elements1 == NULL) {
442 LOG_ERROR("%s", "Out of memory.");
443 if (or_branch_list){
444 free(or_branch_list);
445 }
446 return;
447 }
448 policy_elements1->count = 1;
449 policy_elements1->elements[0] = policy_element1;
450
451 memset(&branch0, 0, sizeof(TPMS_POLICYBRANCH));
452 memset(&branch1, 0, sizeof(TPMS_POLICYBRANCH));
453 branch0.policy = policy_elements0;
454 branch0.name = "branch0";
455 branch0.description = "description branch 0";
456 branch1.policy = policy_elements1;
457 branch1.name = "branch1";
458 branch1.description = "description branch 1";
459 memcpy(&or_branch_list->authorizations[0], &branch0, sizeof(TPMS_POLICYBRANCH));
460 memcpy(&or_branch_list->authorizations[1], &branch1, sizeof(TPMS_POLICYBRANCH));
461 //or_policy.pcrs = pcr_branch_list;
462
463 policy_elements_or = calloc(1, sizeof(TPML_POLICYELEMENTS) + sizeof(TPMT_POLICYELEMENT));
464 if (policy_elements_or == NULL) {
465 LOG_ERROR("%s", "Out of memory.");
466 if (or_branch_list) {
467 free(or_branch_list);
468 }
469 return;
470 }
471 policy_elements_or->count = 1;
472
473 memset(&policy_element_or, 0, sizeof(TPMT_POLICYELEMENT));
474 policy_element_or.element.PolicyOr.branches = or_branch_list;
475 policy_element_or.type = POLICYOR;
476 policy_elements_or->elements[0] = policy_element_or;
477 policy.policy = policy_elements_or;
478
479 //CHECK_BIN(TPMS_POLICY, policy);
480 {
481 char *jso_string1, *jso_string2;
482 json_object *jso = NULL;
483 TSS2_RC rc = ifapi_json_TPMS_POLICY_serialize (&policy, &jso);
484 jso_string1 = strdup(json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY));
485 assert_int_equal (rc, TSS2_RC_SUCCESS);
486 rc = ifapi_json_TPMS_POLICY_deserialize (jso, &policy);
487 assert_int_equal (rc, TSS2_RC_SUCCESS);
488 json_object_put(jso);
489 jso = NULL;
490 rc = ifapi_json_TPMS_POLICY_serialize (&policy, &jso);
491 jso_string2 = strdup(json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY));
492 assert_int_equal (rc, TSS2_RC_SUCCESS);
493 if (strcmp(jso_string1, jso_string2)) {
494 fprintf(stderr,"\n jso: %s\n", jso_string1);
495 fprintf(stderr,"\n jso: %s\n", jso_string2);
496 }
497 assert_string_equal(jso_string1, jso_string2);
498 json_object_put(jso);
499 free(jso_string1);
500 free(jso_string2);
501 }
502 ifapi_cleanup_policy(&policy);
503
504 free(policy_elements_or);
505 free(policy_elements0);
506 free(policy_elements1);
507 free(or_branch_list);
508 free(pcr_value_list);
509 }
510
511 static void
512 check_json_to_bin(void **state)
513 {
514 CHECK_JSON_TO_BIN(UINT64, "22147483647", 22147483647);
515 CHECK_JSON_TO_BIN(UINT64, "\"0xffffffff\"", 0xffffffff);
516 CHECK_JSON_TO_BIN(UINT64, "\"0xfffffffff\"", 0xfffffffff);
517 CHECK_JSON_TO_BIN(UINT32, "\"0xFfffffff\"", 0xffffffff);
518 CHECK_JSON_TO_BIN(UINT16, "\"0xffff\"", 0xffff);
519 }
520
521 static void
522 check_json_structs(void **state)
523 {
524 const char *test_json_TPMS_POLICYTEMPLATE =
525 "{\n"
526 " \"templateHash\": \"0011223344556677889900112233445566778899\"\n"
527 "}";
528 CHECK_JSON(TPMS_POLICYTEMPLATE, test_json_TPMS_POLICYTEMPLATE, test_json_TPMS_POLICYTEMPLATE);
529
530 const char *test_json_TPM2B_PUBLIC_expected =
531 "{\n"
532 " \"size\":0,\n"
533 " \"publicArea\":{\n"
534 " \"type\":\"ECC\",\n"
535 " \"nameAlg\":\"SHA1\",\n"
536 "\"objectAttributes\":{"
537 " \"fixedTPM\":1,"
538 " \"stClear\":0,"
539 " \"fixedParent\":1,"
540 " \"sensitiveDataOrigin\":1,"
541 " \"userWithAuth\":1,"
542 " \"adminWithPolicy\":0,"
543 " \"noDA\":0,"
544 " \"encryptedDuplication\":0,"
545 " \"restricted\":1,"
546 " \"decrypt\":0,"
547 " \"sign\":1"
548 " },"
549 " \"authPolicy\":\"\",\n"
550 " \"parameters\":{\n"
551 " \"symmetric\":{\n"
552 " \"algorithm\":\"NULL\"\n"
553 " },\n"
554 " \"scheme\":{\n"
555 " \"scheme\":\"ECDAA\",\n"
556 " \"details\":{\n"
557 " \"hashAlg\":\"SHA256\",\n"
558 " \"count\":0\n"
559 " }\n"
560 " },\n"
561 " \"curveID\":\"BN_P256\",\n"
562 " \"kdf\":{\n"
563 " \"scheme\":\"NULL\"\n"
564 " }\n"
565 " },\n"
566 " \"unique\":{\n"
567 " \"x\": \"\",\n"
568 " \"y\": \"\"\n"
569 " }\n"
570 " }\n"
571 "}";
572
573 const char *test_json_TPM2B_PUBLIC_src=
574 "{"
575 " \"size\":0,"
576 " \"publicArea\":{"
577 " \"type\":\"ECC\","
578 " \"nameAlg\":\"SHA1\","
579 " \"objectAttributes\":["
580 " \"fixedTPM\","
581 " \"fixedParent\","
582 " \"sensitiveDataOrigin\","
583 " \"userWithAuth\","
584 " \"restricted\","
585 " \"sign\""
586 " ],"
587 " \"authPolicy\":\"\","
588 " \"parameters\":{"
589 " \"symmetric\":{"
590 " \"algorithm\":\"NULL\""
591 " },"
592 " \"scheme\":{"
593 " \"scheme\":\"ECDAA\","
594 " \"details\":{"
595 " \"hashAlg\":\"SHA256\","
596 " \"count\":0"
597 " }"
598 " },"
599 " \"curveID\":\"ECC_BN_P256\","
600 " \"kdf\":{"
601 " \"scheme\":\"NULL\""
602 " }"
603 " },"
604 " \"unique\":{"
605 " \"x\": \"\",\n"
606 " \"y\": \"\"\n"
607 " }"
608 " }"
609 "}"
610 "";
611 const char *test_json_TPM2B_PUBLIC_dwnc_src =
612 "{"
613 " \"size\":0,"
614 " \"publicArea\":{"
615 " \"type\":\"ecc\","
616 " \"nameAlg\":\"sha1\","
617 " \"objectAttributes\":["
618 " \"fixedTPM\","
619 " \"fixedParent\","
620 " \"sensitiveDataOrigin\","
621 " \"userWithAuth\","
622 " \"restricted\","
623 " \"sign\""
624 " ],"
625 " \"authPolicy\":\"\","
626 " \"parameters\":{"
627 " \"symmetric\":{"
628 " \"algorithm\":\"null\""
629 " },"
630 " \"scheme\":{"
631 " \"scheme\":\"ecdaa\","
632 " \"details\":{"
633 " \"hashAlg\":\"sha256\","
634 " \"count\":0"
635 " }"
636 " },"
637 " \"curveID\":\"ecc_BN_P256\","
638 " \"kdf\":{"
639 " \"scheme\":\"null\""
640 " }"
641 " },"
642 " \"unique\":{"
643 " \"x\": \"\",\n"
644 " \"y\": \"\"\n"
645 " }"
646 " }"
647 " }"
648 "}"
649 "";
650
651 CHECK_JSON(TPM2B_PUBLIC, test_json_TPM2B_PUBLIC_src, test_json_TPM2B_PUBLIC_expected);
652 CHECK_JSON(TPM2B_PUBLIC, test_json_TPM2B_PUBLIC_dwnc_src, test_json_TPM2B_PUBLIC_expected);
653
654 const char *test_json_TPMS_ATTEST_certify_src =
655 "{\n"
656 " \"magic\": \"0xff544347\",\n"
657 " \"type\": \"ST_ATTEST_CERTIFY\",\n"
658 " \"qualifiedSigner\": \"0x00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
659 " \"extraData\": \"0x00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
660 " \"clockInfo\": {\n"
661 " \"clock\": 123,\n"
662 " \"resetCount\": 23,\n"
663 " \"restartCount\": 1,\n"
664 " \"safe\": \"yes\"\n"
665 " },\n"
666 " \"firmwareVersion\": 783,\n"
667 " \"attested\": {\n"
668 " \"name\": \"0x00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
669 " \"qualifiedName\": \"0x00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
670 " }\n"
671 "}";
672 const char *test_json_TPMS_ATTEST_certify_expt =
673 "{\n"
674 " \"magic\": \"VALUE\",\n"
675 " \"type\": \"ATTEST_CERTIFY\",\n"
676 " \"qualifiedSigner\": \"00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
677 " \"extraData\": \"00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
678 " \"clockInfo\": {\n"
679 " \"clock\": 123,\n"
680 " \"resetCount\": 23,\n"
681 " \"restartCount\": 1,\n"
682 " \"safe\": \"YES\"\n"
683 " },\n"
684 " \"firmwareVersion\": 783,\n"
685 " \"attested\": {\n"
686 " \"name\": \"00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
687 " \"qualifiedName\": \"00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
688 " }\n"
689 "}";
690 CHECK_JSON(TPMS_ATTEST, test_json_TPMS_ATTEST_certify_src, test_json_TPMS_ATTEST_certify_expt);
691
692 const char *test_json_TPMS_ATTEST_sessionaudit_src =
693 "{\n"
694 " \"magic\": \"0xff544347\",\n"
695 " \"type\": \"ST_ATTEST_SESSION_AUDIT\",\n"
696 " \"qualifiedSigner\": \"0x00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
697 " \"extraData\": \"0x00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
698 " \"clockInfo\": {\n"
699 " \"clock\": [12345,0],\n"
700 " \"resetCount\": 23,\n"
701 " \"restartCount\": 1,\n"
702 " \"safe\": \"yes\"\n"
703 " },\n"
704 " \"firmwareVersion\": [783783,0],\n"
705 " \"attested\": {\n"
706 " \"exclusiveSession\": \"yes\",\n"
707 " \"sessionDigest\": \"0x00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
708 " }\n"
709 "}";
710 const char *test_json_TPMS_ATTEST_sessionaudit_expt =
711 "{\n"
712 " \"magic\": \"VALUE\",\n"
713 " \"type\": \"ATTEST_SESSION_AUDIT\",\n"
714 " \"qualifiedSigner\": \"00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
715 " \"extraData\": \"00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
716 " \"clockInfo\": {\n"
717 " \"clock\": 53021371269120,\n"
718 " \"resetCount\": 23,\n"
719 " \"restartCount\": 1,\n"
720 " \"safe\": \"YES\"\n"
721 " },\n"
722 " \"firmwareVersion\": [783783,0],\n"
723 " \"attested\": {\n"
724 " \"exclusiveSession\": \"YES\",\n"
725 " \"sessionDigest\": \"00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
726 " }\n"
727 "}";
728 CHECK_JSON(TPMS_ATTEST, test_json_TPMS_ATTEST_sessionaudit_src, test_json_TPMS_ATTEST_sessionaudit_expt);
729
730 const char *test_json_TPMS_ATTEST_certifycreation_src =
731 "{\n"
732 " \"magic\": \"0xff544347\",\n"
733 " \"type\": \"ST_ATTEST_CREATION\",\n"
734 " \"qualifiedSigner\": \"0x00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
735 " \"extraData\": \"0x00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
736 " \"clockInfo\": {\n"
737 " \"clock\": 123,\n"
738 " \"resetCount\": 23,\n"
739 " \"restartCount\": 1,\n"
740 " \"safe\": \"yes\"\n"
741 " },\n"
742 " \"firmwareVersion\": [0,783],\n"
743 " \"attested\": {\n"
744 " \"objectName\": \"0x00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
745 " \"creationHash\": \"0x00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
746 " }\n"
747 "}";
748 const char *test_json_TPMS_ATTEST_certifycreation_expt =
749 "{\n"
750 " \"magic\": \"VALUE\",\n"
751 " \"type\": \"ATTEST_CREATION\",\n"
752 " \"qualifiedSigner\": \"00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
753 " \"extraData\": \"00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
754 " \"clockInfo\": {\n"
755 " \"clock\": 123,\n"
756 " \"resetCount\": 23,\n"
757 " \"restartCount\": 1,\n"
758 " \"safe\": \"YES\"\n"
759 " },\n"
760 " \"firmwareVersion\": 783,\n"
761 " \"attested\": {\n"
762 " \"objectName\": \"00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
763 " \"creationHash\": \"00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
764 " }\n"
765 "}";
766 CHECK_JSON(TPMS_ATTEST, test_json_TPMS_ATTEST_certifycreation_src, test_json_TPMS_ATTEST_certifycreation_expt);
767
768 const char *test_json_TPMS_ATTEST_commandaudit_src =
769 "{\n"
770 " \"magic\": \"0xff544347\",\n"
771 " \"type\": \"ST_ATTEST_COMMAND_AUDIT\",\n"
772 " \"qualifiedSigner\": \"0x00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
773 " \"extraData\": \"0x00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
774 " \"clockInfo\": {\n"
775 " \"clock\": 123,\n"
776 " \"resetCount\": 23,\n"
777 " \"restartCount\": 1,\n"
778 " \"safe\": \"yes\"\n"
779 " },\n"
780 " \"firmwareVersion\": 783,\n"
781 " \"attested\": {\n"
782 " \"auditCounter\": 456,\n"
783 " \"digestAlg\": \"sha1\",\n"
784 " \"auditDigest\": \"0x00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
785 " \"commandDigest\": \"0x00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
786 " }\n"
787 "}";
788 const char *test_json_TPMS_ATTEST_commandaudit_expt =
789 "{\n"
790 " \"magic\": \"VALUE\",\n"
791 " \"type\": \"ATTEST_COMMAND_AUDIT\",\n"
792 " \"qualifiedSigner\": \"00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
793 " \"extraData\": \"00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
794 " \"clockInfo\": {\n"
795 " \"clock\": 123,\n"
796 " \"resetCount\": 23,\n"
797 " \"restartCount\": 1,\n"
798 " \"safe\": \"YES\"\n"
799 " },\n"
800 " \"firmwareVersion\": 783,\n"
801 " \"attested\": {\n"
802 " \"auditCounter\": 456,\n"
803 " \"digestAlg\": \"SHA1\",\n"
804 " \"auditDigest\": \"00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
805 " \"commandDigest\": \"00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
806 " }\n"
807 "}";
808 CHECK_JSON(TPMS_ATTEST, test_json_TPMS_ATTEST_commandaudit_src, test_json_TPMS_ATTEST_commandaudit_expt);
809
810 const char *test_json_TPMS_ATTEST_time_src =
811 "{\n"
812 " \"magic\": \"0xff544347\",\n"
813 " \"type\": \"ST_ATTEST_TIME\",\n"
814 " \"qualifiedSigner\": \"0x00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
815 " \"extraData\": \"0x00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
816 " \"clockInfo\": {\n"
817 " \"clock\": 123,\n"
818 " \"resetCount\": 23,\n"
819 " \"restartCount\": 1,\n"
820 " \"safe\": \"yes\"\n"
821 " },\n"
822 " \"firmwareVersion\": 783,\n"
823 " \"attested\": {\n"
824 " \"time\": {\n"
825 " \"time\": 234,\n"
826 " \"clockInfo\": {\n"
827 " \"clock\": 123,\n"
828 " \"resetCount\": 23,\n"
829 " \"restartCount\": 1,\n"
830 " \"safe\": \"yes\"\n"
831 " }\n"
832 " },\n"
833 " \"firmwareVersion\": 783\n"
834 " }\n"
835 "}";
836 const char *test_json_TPMS_ATTEST_time_expt =
837 "{\n"
838 " \"magic\": \"VALUE\",\n"
839 " \"type\": \"ATTEST_TIME\",\n"
840 " \"qualifiedSigner\": \"00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
841 " \"extraData\": \"00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
842 " \"clockInfo\": {\n"
843 " \"clock\": 123,\n"
844 " \"resetCount\": 23,\n"
845 " \"restartCount\": 1,\n"
846 " \"safe\": \"YES\"\n"
847 " },\n"
848 " \"firmwareVersion\": 783,\n"
849 " \"attested\": {\n"
850 " \"time\": {\n"
851 " \"time\": 234,\n"
852 " \"clockInfo\": {\n"
853 " \"clock\": 123,\n"
854 " \"resetCount\": 23,\n"
855 " \"restartCount\": 1,\n"
856 " \"safe\": \"YES\"\n"
857 " }\n"
858 " },\n"
859 " \"firmwareVersion\": 783\n"
860 " }\n"
861 "}";
862 CHECK_JSON(TPMS_ATTEST, test_json_TPMS_ATTEST_time_src, test_json_TPMS_ATTEST_time_expt);
863
864 const char *test_json_TPMS_ATTEST_certifynv_src =
865 "{\n"
866 " \"magic\": \"0xff544347\",\n"
867 " \"type\": \"ST_ATTEST_NV\",\n"
868 " \"qualifiedSigner\": \"0x00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
869 " \"extraData\": \"0x00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
870 " \"clockInfo\": {\n"
871 " \"clock\": 123,\n"
872 " \"resetCount\": 23,\n"
873 " \"restartCount\": 1,\n"
874 " \"safe\": \"yes\"\n"
875 " },\n"
876 " \"firmwareVersion\": 783,\n"
877 " \"attested\": {\n"
878 " \"indexName\": \"0x00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
879 " \"offset\": 10,\n"
880 " \"nvContents\": \"0x00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
881 " }\n"
882 "}";
883 const char *test_json_TPMS_ATTEST_certifynv_expt =
884 "{\n"
885 " \"magic\": \"VALUE\",\n"
886 " \"type\": \"ATTEST_NV\",\n"
887 " \"qualifiedSigner\": \"00010203040506070809a0a1a2a3a4a5a6a7a8a9\",\n"
888 " \"extraData\": \"00010203040506070809b0b1b2b3b4b5b6b7b8b9\",\n"
889 " \"clockInfo\": {\n"
890 " \"clock\": 123,\n"
891 " \"resetCount\": 23,\n"
892 " \"restartCount\": 1,\n"
893 " \"safe\": \"YES\"\n"
894 " },\n"
895 " \"firmwareVersion\": 783,\n"
896 " \"attested\": {\n"
897 " \"indexName\": \"00010203040506070809c0c1c2c3c4c5c6c7c8c9\",\n"
898 " \"offset\": 10,\n"
899 " \"nvContents\": \"00010203040506070809d0d1d2d3d4d5d6d7d8d9\"\n"
900 " }\n"
901 "}";
902 CHECK_JSON(TPMS_ATTEST, test_json_TPMS_ATTEST_certifynv_src, test_json_TPMS_ATTEST_certifynv_expt);
903
904 const char *test_json_TPMT_KEYEDHASH_SCHEME_hmac_src =
905 "{\n"
906 " \"scheme\": \"HMAC\",\n"
907 " \"details\": {\n"
908 " \"hashAlg\": \"SHA256\"\n"
909 " }\n"
910 "}";
911 const char *test_json_TPMT_KEYEDHASH_SCHEME_hmac_expt =
912 "{\n"
913 " \"scheme\": \"HMAC\",\n"
914 " \"details\": {\n"
915 " \"hashAlg\": \"SHA256\"\n"
916 " }\n"
917 "}";
918 CHECK_JSON(TPMT_KEYEDHASH_SCHEME, test_json_TPMT_KEYEDHASH_SCHEME_hmac_src, test_json_TPMT_KEYEDHASH_SCHEME_hmac_expt);
919
920 const char *test_json_TPMT_KEYEDHASH_SCHEME_xor_src =
921 "{\n"
922 " \"scheme\": \"XOR\",\n"
923 " \"details\": {\n"
924 " \"hashAlg\": \"SHA256\",\n"
925 " \"kdf\": \"MGF1\"\n"
926 " }\n"
927 "}";
928 const char *test_json_TPMT_KEYEDHASH_SCHEME_xor_expt =
929 "{\n"
930 " \"scheme\": \"XOR\",\n"
931 " \"details\": {\n"
932 " \"hashAlg\": \"SHA256\",\n"
933 " \"kdf\": \"MGF1\"\n"
934 " }\n"
935 "}";
936 CHECK_JSON(TPMT_KEYEDHASH_SCHEME, test_json_TPMT_KEYEDHASH_SCHEME_xor_src, test_json_TPMT_KEYEDHASH_SCHEME_xor_expt);
937
938 }
939
940 static void
941 check_json_constants(void **state)
942 {
943 CHECK_JSON_SIMPLE(TPMI_ALG_HASH, "\"sha1\"", "\"SHA1\"");
944 CHECK_JSON_SIMPLE(TPMI_ALG_HASH, "\"0x04\"", "\"SHA1\"");
945 CHECK_JSON_SIMPLE(TPMI_ALG_HASH, "4", "\"SHA1\"");
946 }
947
948 static void
949 check_json_numbers(void **state)
950 {
951 CHECK_JSON_SIMPLE(UINT16, "10", "10");
952 CHECK_JSON_SIMPLE(UINT16, "\"0x0a\"", "10");
953 CHECK_JSON_SIMPLE(UINT64, "10000000000000000","[2328306,1874919424]");
954 }
955
956 static void
957 check_json_bits(void **state)
958 {
959 const char *test_json_TPMA_NV_expected =\
960 "{"
961 " \"PPWRITE\":0,"
962 " \"OWNERWRITE\":1,"
963 " \"AUTHWRITE\":1,"
964 " \"POLICYWRITE\":1,"
965 " \"POLICY_DELETE\":1,"
966 " \"WRITELOCKED\":0,"
967 " \"WRITEALL\":0,"
968 " \"WRITEDEFINE\":0,"
969 " \"WRITE_STCLEAR\":0,"
970 " \"GLOBALLOCK\":0,"
971 " \"PPREAD\":0,"
972 " \"OWNERREAD\":1,"
973 " \"AUTHREAD\":1,"
974 " \"POLICYREAD\":1,"
975 " \"NO_DA\":0,"
976 " \"ORDERLY\":1,"
977 " \"CLEAR_STCLEAR\":1,"
978 " \"READLOCKED\":1,"
979 " \"WRITTEN\":1,"
980 " \"PLATFORMCREATE\":0,"
981 " \"READ_STCLEAR\":0,"
982 " \"TPM2_NT\":\"COUNTER\""
983 "}";
984
985 const char *test_json_TPMA_NV_src_array =\
986 "["
987 " \"nv_ownerwrite\","
988 " \"nv_authwrite\","
989 " \"nv_policywrite\","
990 " \"nv_policy_delete\","
991 " \"nv_ownerread\","
992 " \"nv_authread\","
993 " \"nv_policyread\","
994 " \"nv_orderly\","
995 " \"nv_clear_stclear\","
996 " \"nv_readlocked\","
997 " \"nv_written\","
998 " {"
999 " \"TPM2_NT\": \"NT_COUNTER\""
1000 " }"
1001 "]";
1002
1003 const char *test_json_TPMA_NV_src_struct =\
1004 "{"
1005 " \"TPMA_NV_OWNERWRITE\":\"YES\","
1006 " \"TPMA_NV_AUTHWRITE\":\"yes\","
1007 " \"TPMA_NV_POLICYWRITE\":\"TPM2_YES\","
1008 " \"TPMA_NV_POLICY_DELETE\":\"tpm2_yes\","
1009 " \"TPMA_NV_OWNERREAD\":\"SET\","
1010 " \"TPMA_NV_AUTHREAD\":\"set\","
1011 " \"TPMA_NV_POLICYREAD\":1,"
1012 " \"TPMA_NV_ORDERLY\":1,"
1013 " \"TPMA_NV_CLEAR_STCLEAR\":1,"
1014 " \"TPMA_NV_READLOCKED\":1,"
1015 " \"TPMA_NV_WRITTEN\":1,"
1016 " \"TPM2_NT\":1"
1017 " }";
1018
1019 CHECK_JSON_SIMPLE(TPMA_NV, test_json_TPMA_NV_src_array, test_json_TPMA_NV_expected);
1020 CHECK_JSON_SIMPLE(TPMA_NV, test_json_TPMA_NV_src_struct, test_json_TPMA_NV_expected);
1021 }
1022
1023 static void
1024 check_json_policy(void **state)
1025 {
1026 const char *test_json_policy_nv_src = \
1027 "{"
1028 " \"description\":\"Description pol_nv\","
1029 " \"policyDigests\":["
1030 " ],"
1031 " \"policyAuthorizations\":["
1032 " ],"
1033 " \"policy\":["
1034 " {"
1035 " \"type\": \"POLICYNV\","
1036 " \"nvPath\": \"myNV\","
1037 " \"operandB\": \"01030304\""
1038 " }"
1039 " ]"
1040 "}";
1041
1042 const char *test_json_policy_nv_expected = \
1043 "{"
1044 " \"description\":\"Description pol_nv\","
1045 " \"policyDigests\":["
1046 " ],"
1047 " \"policyAuthorizations\":["
1048 " ],"
1049 " \"policy\":["
1050 " {"
1051 " \"type\": \"POLICYNV\","
1052 " \"nvPath\": \"myNV\","
1053 " \"operandB\": \"01030304\""
1054 " }"
1055 " ]"
1056 "}";
1057
1058
1059 // CHECK_JSON(TPMS_POLICY, test_json_policy_nv_src, test_json_policy_nv_expected);
1060 {
1061 TPMS_POLICY out;
1062 TSS2_RC rc;
1063 json_object *jso = json_tokener_parse(test_json_policy_nv_src);
1064 if (!jso) fprintf(stderr, "JSON parsing failed\n");
1065 assert_non_null(jso);
1066 rc = ifapi_json_TPMS_POLICY_deserialize (jso, &out);
1067 if (rc) fprintf(stderr, "Deserialization failed\n");
1068 assert_int_equal (rc, TSS2_RC_SUCCESS);
1069 json_object_put(jso);
1070 jso = NULL;
1071 rc = ifapi_json_TPMS_POLICY_serialize (&out, &jso);
1072 assert_int_equal (rc, TSS2_RC_SUCCESS);
1073 assert_non_null(jso);
1074 const char *jso_string = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY);
1075 assert_non_null(jso_string);
1076 char *string1 = normalize(jso_string);
1077 char *string2 = normalize(test_json_policy_nv_expected);
1078 assert_string_equal(string1, string2);
1079 json_object_put(jso);
1080 ifapi_cleanup_policy(&out);
1081 free(string1);
1082 free(string2);
1083 }
1084
1085 const char *test_json_policy_or_src = \
1086 "{"
1087 " \"description\":\"hareness description\","
1088 " \"policyDigests\":["
1089 " {"
1090 " \"hashAlg\":\"SHA256\","
1091 " \"digest\":\"59215cb6c21a60e26b2cc479334a021113611903795507c1227659e2aef23d16\""
1092 " }"
1093 " ],"
1094 " \"policy\":["
1095 " {"
1096 " \"type\":\"POLICYOR\","
1097 " \"policyDigests\":["
1098 " {"
1099 " \"hashAlg\":\"SHA256\","
1100 " \"digest\":\"59215cb6c21a60e26b2cc479334a021113611903795507c1227659e2aef23d16\""
1101 " }"
1102 " ],"
1103 " \"branches\":["
1104 " {"
1105 " \"name\":\"branch1\","
1106 " \"description\":\"description branch 1\","
1107 " \"policy\":["
1108 " {"
1109 " \"type\":\"POLICYPCR\","
1110 " \"policyDigests\":["
1111 " {"
1112 " \"hashAlg\":\"SHA256\","
1113 " \"digest\":\"17d552f8e39ad882f6b3c09ae139af59616bf6a63f4093d6d20e9e1b9f7cdb6e\""
1114 " }"
1115 " ],"
1116 " \"pcrs\":["
1117 " {"
1118 " \"pcr\":16,"
1119 " \"hashAlg\":\"SHA1\","
1120 " \"digest\":\"0000000000000000000000000000000000000000\""
1121 " }"
1122 " ]"
1123 " }"
1124 " ],"
1125 " \"policyDigests\":["
1126 " {"
1127 " \"hashAlg\":\"SHA256\","
1128 " \"digest\":\"17d552f8e39ad882f6b3c09ae139af59616bf6a63f4093d6d20e9e1b9f7cdb6e\""
1129 " }"
1130 " ]"
1131 " },"
1132 " {"
1133 " \"name\":\"branch1\","
1134 " \"description\":\"description branch 1\","
1135 " \"policy\":["
1136 " {"
1137 " \"type\":\"POLICYPCR\","
1138 " \"policyDigests\":["
1139 " {"
1140 " \"hashAlg\":\"SHA256\","
1141 " \"digest\":\"17d552f8e39ad882f6b3c09ae139af59616bf6a63f4093d6d20e9e1b9f7cdb6e\""
1142 " }"
1143 " ],"
1144 " \"pcrs\":["
1145 " {"
1146 " \"pcr\":16,"
1147 " \"hashAlg\":\"SHA1\","
1148 " \"digest\":\"0000000000000000000000000000000000000000\""
1149 " }"
1150 " ]"
1151 " }"
1152 " ],"
1153 " \"policyDigests\":["
1154 " {"
1155 " \"hashAlg\":\"SHA256\","
1156 " \"digest\":\"17d552f8e39ad882f6b3c09ae139af59616bf6a63f4093d6d20e9e1b9f7cdb6e\""
1157 " }"
1158 " ]"
1159 " }"
1160 " ]"
1161 " }"
1162 " ]"
1163 "}";
1164
1165 char *test_json_policy_or_expected = strdup(test_json_policy_or_src);
1166 if (test_json_policy_or_expected == NULL){
1167 LOG_ERROR("%s", "Out of memory.");
1168 return;
1169 }
1170 // CHECK_JSON(TPMS_POLICY, test_json_policy_or_src, test_json_policy_or_expected);
1171 {
1172 TPMS_POLICY out;
1173 TSS2_RC rc;
1174 json_object *jso = json_tokener_parse(test_json_policy_or_src);
1175 if (!jso) fprintf(stderr, "JSON parsing failed\n");
1176 assert_non_null(jso);
1177 rc = ifapi_json_TPMS_POLICY_deserialize (jso, &out);
1178 if (rc) fprintf(stderr, "Deserialization failed\n");
1179 assert_int_equal (rc, TSS2_RC_SUCCESS);
1180 json_object_put(jso);
1181 jso = NULL;
1182 rc = ifapi_json_TPMS_POLICY_serialize (&out, &jso);
1183 assert_int_equal (rc, TSS2_RC_SUCCESS);
1184 assert_non_null(jso);
1185 const char *jso_string = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY);
1186 assert_non_null(jso_string);
1187 char *string1 = normalize(jso_string);
1188 char *string2 = normalize(test_json_policy_or_expected);
1189 assert_string_equal(string1, string2);
1190 json_object_put(jso);
1191 ifapi_cleanup_policy(&out);
1192 free(string1);
1193 free(string2);
1194 }
1195 free(test_json_policy_or_expected);
1196 }
1197
1198
1199 static void
1200 check_json_tpm2bs(void **state)
1201 {
1202 CHECK_JSON(TPM2B_DIGEST, "\"0x0102\"", "\"0102\"");
1203 CHECK_JSON(TPM2B_DIGEST, "\"0102\"", "\"0102\"");
1204 CHECK_JSON(TPM2B_DIGEST, "\"caffee\"", "\"caffee\"");
1205 }
1206
1207 static void
1208 check_error(void **state)
1209 {
1210 /* Value is > then max value for UINT */
1211 CHECK_ERROR(UINT16, "\"0x10000\"", TSS2_FAPI_RC_BAD_VALUE);
1212 CHECK_ERROR(UINT32, "\"0x100000000\"", TSS2_FAPI_RC_BAD_VALUE);
1213
1214 /* Digest/list is too large*/
1215 CHECK_ERROR(TPM2B_DIGEST, "\"0x0102222222222222222222222222222222222222222222222222222"
1216 "22222222222222222222222222222222222222222222222222222222222222222222222222222\"",
1217 TSS2_FAPI_RC_BAD_VALUE);
1218
1219 /* Illegal values */
1220 CHECK_ERROR(TPMI_ALG_HASH, "\"SHA9999\"", TSS2_FAPI_RC_BAD_VALUE);
1221 CHECK_ERROR(TPM2B_DIGEST, "\"xxxx\"", TSS2_FAPI_RC_BAD_VALUE);
1222 CHECK_ERROR(TPM2B_DIGEST, "\"0x010x\"", TSS2_FAPI_RC_BAD_VALUE);
1223 }
1224
1225
1226 static void
1227 check_tpmjson_tofromtxt(void **state)
1228 {
1229 const char *testcase_alg_id[] = { "\"TPM_ALG_ID_SHA1\"", "\"TPM2_ALG_ID_SHA1\"",
1230 "\"ALG_ID_SHA1\"", "\"SHA1\"", "\"ALG_SHA1\"",
1231 "\"tpm2_alg_id_sha1\"", "\"sha1\"", "\"0x0004\"" };
1232 const char *expected_ald_id = { "\"SHA1\"" };
1233 for (size_t i = 0; i < sizeof(testcase_alg_id) / sizeof(testcase_alg_id[0]); i++) {
1234 CHECK_JSON_SIMPLE(TPM2_ALG_ID, testcase_alg_id[i], expected_ald_id);
1235 }
1236
1237 const char *testcase_ecc_curve[] = { "\"TPM2_ECC_NIST_P256\"", "\"ECC_NIST_P256\"",
1238 "\"NIST_P256\"", "\"0x0003\"", "\"nist_p256\"" };
1239 const char *expected_ecc_curve = { "\"NIST_P256\"" };
1240 for (size_t i = 0; i < sizeof(testcase_ecc_curve) / sizeof(testcase_ecc_curve[0]); i++) {
1241 CHECK_JSON_SIMPLE(TPM2_ECC_CURVE, testcase_ecc_curve[i], expected_ecc_curve);
1242 }
1243
1244 const char *testcase_cc[] = { "\"TPM2_CC_Startup\"", "\"CC_Startup\"",
1245 "\"Startup\"", "\"0x00000144\"" };
1246 const char *expected_cc = { "\"Startup\"" };
1247 for (size_t i = 0; i < sizeof(testcase_cc) / sizeof(testcase_cc[0]); i++) {
1248 CHECK_JSON_SIMPLE(TPM2_CC, testcase_cc[i], expected_cc);
1249 }
1250
1251 const char *testcase_eo[] = { "\"TPM2_EO_EQ\"", "\"EO_EQ\"",
1252 "\"EQ\"", "\"0x0000\"" };
1253 const char *expected_eo = { "\"EQ\"" };
1254 for (size_t i = 0; i < sizeof(testcase_eo) / sizeof(testcase_eo[0]); i++) {
1255 CHECK_JSON_SIMPLE(TPM2_EO, testcase_eo[i], expected_eo);
1256 }
1257
1258 const char *testcase_st[] = { "\"TPM2_ST_NO_SESSIONS\"", "\"ST_NO_SESSIONS\"",
1259 "\"no_SESSIONS\"", "\"0x8001\"" };
1260 const char *expected_st = { "\"NO_SESSIONS\"" };
1261 for (size_t i = 0; i < sizeof(testcase_st) / sizeof(testcase_st[0]); i++) {
1262 CHECK_JSON_SIMPLE(TPM2_ST, testcase_st[i], expected_st);
1263 }
1264
1265 const char *testcase_pt_pcr[] = { "\"TPM2_PT_PCR_EXTEND_L0\"", "\"PT_PCR_EXTEND_L0\"",
1266 "\"PCR_EXTEND_L0\"", "\"EXTEND_L0\"" };
1267 const char *expected_pt_pcr = { "\"EXTEND_L0\"" };
1268 for (size_t i = 0; i < sizeof(testcase_pt_pcr) / sizeof(testcase_pt_pcr[0]); i++) {
1269 CHECK_JSON_SIMPLE(TPM2_PT_PCR, testcase_pt_pcr[i], expected_pt_pcr);
1270 }
1271
1272 const char *testcase_alg_public[] = { "\"TPM2_ALG_RSA\"", "\"ALG_RSA\"",
1273 "\"RSA\"", "\"0x0001\"" };
1274 const char *expected_alg_public = { "\"RSA\"" };
1275 for (size_t i = 0; i < sizeof(testcase_alg_public) / sizeof(testcase_alg_public[0]); i++) {
1276 CHECK_JSON_SIMPLE(TPMI_ALG_PUBLIC, testcase_alg_public[i], expected_alg_public);
1277 }
1278 }
1279
1280 int
1281 main(int argc, char *argv[])
1282 {
1283 const struct CMUnitTest tests[] = {
1284 cmocka_unit_test(check_tpmjson_tofromtxt),
1285 cmocka_unit_test(check_json_structs),
1286 cmocka_unit_test(check_json_constants),
1287 cmocka_unit_test(check_json_numbers),
1288 cmocka_unit_test(check_json_bits),
1289 cmocka_unit_test(check_json_tpm2bs),
1290 cmocka_unit_test(check_json_to_bin),
1291 cmocka_unit_test(check_bin),
1292 cmocka_unit_test(check_policy_bin),
1293 cmocka_unit_test(check_error),
1294 cmocka_unit_test(check_json_policy),
1295 };
1296 return cmocka_run_group_tests(tests, NULL, NULL);
1297 }
1010 #include <inttypes.h>
1111 #include <stdio.h>
1212 #include <stdbool.h>
13 #include <string.h>
1314
1415 #include <setjmp.h>
1516 #include <cmocka.h>
88 #endif
99
1010 #include <inttypes.h>
11 #include <stdarg.h>
1112 #include <stdbool.h>
1213 #include <stdio.h>
1314 #include <string.h>
3738 0xca, 0xfe, 0xba, 0xbe,
3839 0xfe, 0xef
3940 };
41 int
42 __real_open(const char *pathname, int flags, ...);
43 /* wrap function for open required to test init */
44 int
45 __wrap_open(const char *pathname, int flags, ...)
46 {
47 const char* pathname_prefix_dev = "/dev";
48 if (strncmp(pathname, pathname_prefix_dev, strlen(pathname_prefix_dev)) == 0) {
49 return mock_type (int);
50 } else {
51 /* only mock opening of device files as the open() syscall is needed
52 for code coverage reports as well */
53 return __real_open(pathname, flags);
54 }
55 }
4056 /**
4157 * When passed all NULL values ensure that we get back the expected RC
4258 * indicating bad values.
6278 ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
6379 assert_int_equal (ret, TSS2_RC_SUCCESS);
6480 }
81 /* Test the failure of opening a specified device file */
82 static void
83 tcti_device_init_conf_fail (void **state)
84 {
85 size_t tcti_size = 0;
86 TSS2_RC ret = TSS2_RC_SUCCESS;
87 TSS2_TCTI_CONTEXT *ctx = NULL;
88
89 ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
90 assert_true (ret == TSS2_RC_SUCCESS);
91 ctx = calloc (1, tcti_size);
92 assert_non_null (ctx);
93 errno = ENOENT; /* No such file or directory */
94 will_return (__wrap_open, -1);
95 ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, "/dev/nonexistent");
96 assert_true (ret == TSS2_TCTI_RC_IO_ERROR);
97
98 free(ctx);
99 }
100 /* Test the device file recognition if no config string was specified */
101 static void
102 tcti_device_init_conf_default_fail (void **state)
103 {
104 size_t tcti_size = 0;
105 TSS2_RC ret = TSS2_RC_SUCCESS;
106 TSS2_TCTI_CONTEXT *ctx = NULL;
107
108 ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
109 assert_true (ret == TSS2_RC_SUCCESS);
110 ctx = calloc (1, tcti_size);
111 assert_non_null (ctx);
112 errno = EACCES; /* Permission denied */
113 will_return (__wrap_open, -1);
114 will_return (__wrap_open, -1);
115 ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, NULL);
116 assert_true (ret == TSS2_TCTI_RC_IO_ERROR);
117
118 free(ctx);
119 }
120 /* Test the device file recognition if no config string was specified */
121 static void
122 tcti_device_init_conf_default_success (void **state)
123 {
124 size_t tcti_size = 0;
125 TSS2_RC ret = TSS2_RC_SUCCESS;
126 TSS2_TCTI_CONTEXT *ctx = NULL;
127
128 ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
129 assert_true (ret == TSS2_RC_SUCCESS);
130 ctx = calloc (1, tcti_size);
131 assert_non_null (ctx);
132 will_return (__wrap_open, 3);
133 ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, NULL);
134 assert_true (ret == TSS2_RC_SUCCESS);
135
136 free(ctx);
137 }
65138 /* wrap functions for read & write required to test receive / transmit */
66139 ssize_t
67140 __wrap_read (int fd, void *buf, size_t count)
103176 assert_true (ret == TSS2_RC_SUCCESS);
104177 ctx = calloc (1, tcti_size);
105178 assert_non_null (ctx);
179 will_return (__wrap_open, 3);
106180 ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, "/dev/null");
107181 assert_true (ret == TSS2_RC_SUCCESS);
108182
354428 const struct CMUnitTest tests[] = {
355429 cmocka_unit_test (tcti_device_init_all_null_test),
356430 cmocka_unit_test(tcti_device_init_size_test),
431 cmocka_unit_test(tcti_device_init_conf_fail),
432 cmocka_unit_test(tcti_device_init_conf_default_fail),
433 cmocka_unit_test(tcti_device_init_conf_default_success),
357434 cmocka_unit_test_setup_teardown (tcti_device_get_poll_handles_test,
358435 tcti_device_setup,
359436 tcti_device_teardown),
367444 tcti_device_setup,
368445 tcti_device_teardown),
369446 cmocka_unit_test_setup_teardown (tcti_device_receive_buffer_lt_response,
370 tcti_device_setup,
371 tcti_device_teardown),
372 cmocka_unit_test_setup_teardown (tcti_device_transmit_success,
373447 tcti_device_setup,
374448 tcti_device_teardown),
375449 cmocka_unit_test_setup_teardown (tcti_device_transmit_success,
6565 will_return (__wrap_tcti_from_init, TEST_RC);
6666 will_return (__wrap_tcti_from_init, tcti_ctx);
6767 will_return (__wrap_tcti_from_init, TEST_RC);
68 #ifdef TCTI_MSSIM
6869 will_return (__wrap_tcti_from_init, tcti_ctx);
6970 will_return (__wrap_tcti_from_init, TEST_RC);
71 #endif
7072 rc = tctildr_get_default (&tcti_ctx, NULL);
7173 assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
7274
131131
132132 tctildr_finalize (context);
133133
134 free (context);
135
134136 return 0;
135137 }
136138 static void
273273 will_return (__wrap_calloc, NULL);
274274
275275 rc = Tss2_TctiLdr_Initialize_Ex (NULL, NULL, &ctx);
276 assert_int_equal (rc, TSS2_RC_SUCCESS);
276 assert_int_equal (rc, TSS2_TCTI_RC_MEMORY);
277277 }
278278 static void
279279 tctildr_init_ex_success_test (void **state)