From 8bf8ae340fd1c4f58548c9df52ed3d1547c40b88 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 6 Feb 2018 16:27:50 -0800 Subject: [PATCH] wolfTPM v1.0 TPM 2.0 support: * Support for all TPM2 API's using TIS and SPI IO callback. * Helper for getting TPM return code string `TPM2_GetRCString`. * TPM 2.0 demo code in `examples/tpm/tpm2_demo.c` with support for STM32 CubeMX SPI as reference. Requires wolfSSL (https://github.com/wolfSSL/wolfssl/pull/1344) --- .gitignore | 23 + IDE/OPENSTM32/.cproject | 176 + IDE/OPENSTM32/.project | 27 + IDE/OPENSTM32/Inc/wolftpm_example.h | 47 + IDE/OPENSTM32/README.md | 27 + IDE/OPENSTM32/Src/main.c | 361 ++ IDE/OPENSTM32/Src/wolftpm_example.c | 123 + IDE/OPENSTM32/include.am | 13 + IDE/OPENSTM32/wolfSTM32.cfg | 13 + IDE/OPENSTM32/wolfSTM32.ioc | 213 ++ IDE/OPENSTM32/wolfSTM32.xml | 9 + IDE/include.am | 5 + Makefile.am | 102 + README.md | 162 +- autogen.sh | 45 + commit-tests.sh | 24 + configure.ac | 143 + examples/include.am | 4 + examples/tpm/include.am | 4 + examples/tpm/tpm2_demo.c | 264 ++ m4/ax_add_am_macro.m4 | 29 + m4/ax_am_jobserver.m4 | 55 + m4/ax_am_macros.m4 | 44 + m4/ax_append_compile_flags.m4 | 65 + m4/ax_append_flag.m4 | 69 + m4/ax_append_link_flags.m4 | 63 + m4/ax_append_to_file.m4 | 27 + m4/ax_check_compile_flag.m4 | 72 + m4/ax_check_link_flag.m4 | 71 + m4/ax_count_cpus.m4 | 57 + m4/ax_create_generic_config.m4 | 195 + m4/ax_debug.m4 | 63 + m4/ax_file_escapes.m4 | 30 + m4/ax_harden_compiler_flags.m4 | 236 ++ m4/ax_print_to_file.m4 | 27 + m4/ax_pthread.m4 | 320 ++ m4/ax_vcs_checkout.m4 | 75 + m4/have_wolfssl.m4 | 57 + m4/hexversion.m4 | 6 + m4/lib-ld.m4 | 110 + m4/lib-link.m4 | 767 ++++ m4/lib-prefix.m4 | 221 ++ m4/visibility.m4 | 77 + m4/wolfssl_darwin_clang.m4 | 37 + pre-commit.sh | 36 + src/include.am | 12 + src/tpm2.c | 5081 +++++++++++++++++++++++++++ wolftpm/include.am | 8 + wolftpm/tpm2.h | 2884 +++++++++++++++ wolftpm/version.h | 42 + wolftpm/version.h.in | 42 + wolftpm/visibility.h | 61 + 52 files changed, 12722 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 IDE/OPENSTM32/.cproject create mode 100644 IDE/OPENSTM32/.project create mode 100644 IDE/OPENSTM32/Inc/wolftpm_example.h create mode 100644 IDE/OPENSTM32/README.md create mode 100644 IDE/OPENSTM32/Src/main.c create mode 100644 IDE/OPENSTM32/Src/wolftpm_example.c create mode 100644 IDE/OPENSTM32/include.am create mode 100644 IDE/OPENSTM32/wolfSTM32.cfg create mode 100644 IDE/OPENSTM32/wolfSTM32.ioc create mode 100644 IDE/OPENSTM32/wolfSTM32.xml create mode 100644 IDE/include.am create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100755 commit-tests.sh create mode 100644 configure.ac create mode 100644 examples/include.am create mode 100644 examples/tpm/include.am create mode 100644 examples/tpm/tpm2_demo.c create mode 100644 m4/ax_add_am_macro.m4 create mode 100644 m4/ax_am_jobserver.m4 create mode 100644 m4/ax_am_macros.m4 create mode 100644 m4/ax_append_compile_flags.m4 create mode 100644 m4/ax_append_flag.m4 create mode 100644 m4/ax_append_link_flags.m4 create mode 100644 m4/ax_append_to_file.m4 create mode 100644 m4/ax_check_compile_flag.m4 create mode 100644 m4/ax_check_link_flag.m4 create mode 100644 m4/ax_count_cpus.m4 create mode 100644 m4/ax_create_generic_config.m4 create mode 100644 m4/ax_debug.m4 create mode 100644 m4/ax_file_escapes.m4 create mode 100644 m4/ax_harden_compiler_flags.m4 create mode 100644 m4/ax_print_to_file.m4 create mode 100644 m4/ax_pthread.m4 create mode 100644 m4/ax_vcs_checkout.m4 create mode 100644 m4/have_wolfssl.m4 create mode 100644 m4/hexversion.m4 create mode 100644 m4/lib-ld.m4 create mode 100644 m4/lib-link.m4 create mode 100644 m4/lib-prefix.m4 create mode 100644 m4/visibility.m4 create mode 100644 m4/wolfssl_darwin_clang.m4 create mode 100755 pre-commit.sh create mode 100644 src/include.am create mode 100644 src/tpm2.c create mode 100644 wolftpm/include.am create mode 100644 wolftpm/tpm2.h create mode 100644 wolftpm/version.h create mode 100644 wolftpm/version.h.in create mode 100755 wolftpm/visibility.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d1d2d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.metadata +language.settings.xml +src/config.h.in +autom4te.cache +build-aux +aclocal.m4 +configure +Makefile.in +m4 +aminclude.am +config.log +config.status +libtool +Makefile +wolftpm-config +.dirstamp +*.la +*.lo +config.h +stamp-h1 +test-suite.log +src/.deps +src/.libs diff --git a/IDE/OPENSTM32/.cproject b/IDE/OPENSTM32/.cproject new file mode 100644 index 0000000..75f6e4f --- /dev/null +++ b/IDE/OPENSTM32/.cproject @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/OPENSTM32/.project b/IDE/OPENSTM32/.project new file mode 100644 index 0000000..f4d3672 --- /dev/null +++ b/IDE/OPENSTM32/.project @@ -0,0 +1,27 @@ + + + wolfSTM32_CubeMX + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + fr.ac6.mcu.ide.core.MCUProjectNature + + diff --git a/IDE/OPENSTM32/Inc/wolftpm_example.h b/IDE/OPENSTM32/Inc/wolftpm_example.h new file mode 100644 index 0000000..a005fe7 --- /dev/null +++ b/IDE/OPENSTM32/Inc/wolftpm_example.h @@ -0,0 +1,47 @@ +/* wolftpm_example.h + * + * Copyright (C) 2006-2017 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifndef WOLFTPM_EXAMPLE_H_ +#define WOLFTPM_EXAMPLE_H_ + +#include +#include +#include + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#include +#include + +#include + +void wolfTPMDemo(void const * argument); + + +#endif /* WOLFTPM_EXAMPLE_H_ */ diff --git a/IDE/OPENSTM32/README.md b/IDE/OPENSTM32/README.md new file mode 100644 index 0000000..ec1e618 --- /dev/null +++ b/IDE/OPENSTM32/README.md @@ -0,0 +1,27 @@ +# wolfSSL STM32F2/F4 Example for Open STM32 Tools System Workbench + + +## Requirements + +* STM32CubeMX: STM32 CubeMX HAL code generation tool - [http://www.st.com/en/development-tools/stm32cubemx.html](http://www.st.com/en/development-tools/stm32cubemx.html) +* SystemWorkbench for STM32 - [http://www.st.com/en/development-tools/sw4stm32.html](http://www.st.com/en/development-tools/sw4stm32.html) + +## Setup + +1. Using the STM32CubeMX tool, load the `/IDE/OPENSTM32/wolfSTM32.ino` file. +2. Adjust the HAL options based on your specific micro-controller. +3. Generate source code. +4. Run `SystemWorkbench` and choose a new workspace location for this project. +5. Import `wolfSTM32' project from `/IDE/OPENSTM32/`. +6. Adjust the micro-controller define in `Project Settings -> C/C++ General -> Paths and Symbols -> Symbols -> GNU C`. Example uses `STM32F437xx`, but should be changed to reflect your micro-controller type. +7. Build and Run + +Note: You may need to manually copy over the CubeMX HAL files for `stm32f4xx_hal_cryp.c`, `stm32f4xx_hal_cryp_ex.c`, `stm32f4xx_hal_cryp.h`, `stm32f4xx_hal_cryp_ex.h`. Also uncomment the `#define HAL_CRYP_MODULE_ENABLED` line in `stm32f4xx_hal_conf.h`. + +## Configuration + +The settings for the wolfSTM32 project are located in `/IDE/OPENSTM32/Inc/user_settings.h`. + +## Support + +For questions please email [support@wolfssl.com](mailto:support@wolfssl.com) \ No newline at end of file diff --git a/IDE/OPENSTM32/Src/main.c b/IDE/OPENSTM32/Src/main.c new file mode 100644 index 0000000..b59c411 --- /dev/null +++ b/IDE/OPENSTM32/Src/main.c @@ -0,0 +1,361 @@ +/* main.c + * + * Copyright (C) 2006-2017 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wolfssl_example.h" + + +/* Private variables ---------------------------------------------------------*/ + +RNG_HandleTypeDef hrng; +RTC_HandleTypeDef hrtc; +SPI_HandleTypeDef hspi1; +UART_HandleTypeDef huart4; +CRYP_HandleTypeDef CrypHandle; +HASH_HandleTypeDef HashHandle; + +osThreadId defaultTaskHandle; + +int __errno; + +/* Private function prototypes -----------------------------------------------*/ +static void SystemClock_Config(void); +static void Error_Handler(void); + +static void MX_GPIO_Init(void); + +static void MX_RNG_Init(void); +static void MX_RTC_Init(void); +static void MX_SPI1_Init(void); +static void MX_UART4_Init(void); + + +int main(void) +{ + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* Configure the system clock */ + SystemClock_Config(); + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + + MX_RNG_Init(); + MX_RTC_Init(); + MX_SPI1_Init(); + MX_UART4_Init(); + +#ifndef FREERTOS + wolfTPMDemo(NULL); +#else + /* Create the thread(s) */ + /* definition and creation of defaultTask */ + osThreadDef(defaultTask, wolfTPMDemo, osPriorityNormal, 0, 24000); + defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); + + + /* Start scheduler */ + osKernelStart(); + + /* We should never get here as control is now taken by the scheduler */ + + /* Infinite loop */ + while (1) {} +#endif +} + +/** System Clock Configuration +*/ +static void SystemClock_Config(void) +{ + + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + __HAL_RCC_PWR_CLK_ENABLE(); + + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = 16; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLM = 8; + RCC_OscInitStruct.PLL.PLLN = 120; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 5; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) + { + Error_Handler(); + } + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); + + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); + + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0); +} + +/* RNG init function */ +static void MX_RNG_Init(void) +{ + + hrng.Instance = RNG; + if (HAL_RNG_Init(&hrng) != HAL_OK) + { + Error_Handler(); + } + +} + +/* RTC init function */ +static void MX_RTC_Init(void) +{ + + RTC_TimeTypeDef sTime; + RTC_DateTypeDef sDate; + + /**Initialize RTC and set the Time and Date + */ + hrtc.Instance = RTC; + hrtc.Init.HourFormat = RTC_HOURFORMAT_24; + hrtc.Init.AsynchPrediv = 127; + hrtc.Init.SynchPrediv = 255; + hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; + hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + if (HAL_RTC_Init(&hrtc) != HAL_OK) + { + Error_Handler(); + } + + sTime.Hours = 0x0; + sTime.Minutes = 0x0; + sTime.Seconds = 0x0; + sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + sTime.StoreOperation = RTC_STOREOPERATION_RESET; + if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) + { + Error_Handler(); + } + + sDate.WeekDay = RTC_WEEKDAY_MONDAY; + sDate.Month = RTC_MONTH_JANUARY; + sDate.Date = 0x1; + sDate.Year = 0x0; + + /**Enable the reference Clock input + */ + if (HAL_RTCEx_SetRefClock(&hrtc) != HAL_OK) + { + Error_Handler(); + } + + if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) + { + Error_Handler(); + } + + /**Enable the TimeStamp + */ + if (HAL_RTCEx_SetTimeStamp(&hrtc, RTC_TIMESTAMPEDGE_RISING, RTC_TIMESTAMPPIN_POS1) != HAL_OK) + { + Error_Handler(); + } + +} + + +/* SPI1 init function */ +static void MX_SPI1_Init(void) +{ + + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } + +} + +/* UART4 init function */ +static void MX_UART4_Init(void) +{ + + huart4.Instance = UART4; + huart4.Init.BaudRate = 115200; + huart4.Init.WordLength = UART_WORDLENGTH_8B; + huart4.Init.StopBits = UART_STOPBITS_1; + huart4.Init.Parity = UART_PARITY_NONE; + huart4.Init.Mode = UART_MODE_TX_RX; + huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart4.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart4) != HAL_OK) + { + Error_Handler(); + } + + // Turn off buffers, so I/O occurs immediately + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); +} + +int _write (int fd, char *ptr, int len) +{ + (void)fd; + + /* Write "len" of char from "ptr" to file id "fd" + * Return number of char written. + * Need implementing with UART here. */ + HAL_UART_Transmit(&huart4, (uint8_t *)ptr, len, 0xFFFF); + + return len; +} + +int _read (int fd, char *ptr, int len) +{ + /* Read "len" of char to "ptr" from file id "fd" + * Return number of char read. + * Need implementing with UART here. */ + (void)fd; + + return HAL_UART_Receive(&huart4, (uint8_t*)ptr, len, 0xFFFF); +} + +void _ttywrch(int ch) { + /* Write one char "ch" to the default console + * Need implementing with UART here. */ + _write(0, (char*)&ch, 1); +} + + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI +*/ +static void MX_GPIO_Init(void) +{ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + +} + + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM1 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + if (htim->Instance == TIM1) { + HAL_IncTick(); + } +} + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +static void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler */ +} + +#ifdef USE_FULL_ASSERT + +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ + +} + +#endif + +/** + * @} + */ + +/** + * @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/IDE/OPENSTM32/Src/wolftpm_example.c b/IDE/OPENSTM32/Src/wolftpm_example.c new file mode 100644 index 0000000..20446e2 --- /dev/null +++ b/IDE/OPENSTM32/Src/wolftpm_example.c @@ -0,0 +1,123 @@ +/* wolftpm_example.c + * + * Copyright (C) 2006-2017 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#include "wolfssl_example.h" + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +/* UART definitions */ +extern UART_HandleTypeDef huart4; +extern SPI_HandleTypeDef hspi1; + + +#ifdef WOLF_TPM2 +extern int TPM2_Demo(void); +#endif + + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ +typedef struct func_args { + int argc; + char** argv; + int return_code; +} func_args; + +const char menu1[] = "\r\n" + "\tt. WolfCrypt Test\r\n" + "\tb. WolfCrypt Benchmark\r\n" + "\tm. WolfCrypt TPM 2.0 Test\r\n"; + +/***************************************************************************** + * Private functions + ****************************************************************************/ + + +/***************************************************************************** + * Public functions + ****************************************************************************/ +void wolfCryptDemo(void const * argument) +{ + uint8_t buffer[2]; + func_args args; + + while (1) { + printf("\r\n\t\t\t\tMENU\r\n"); + printf(menu1); + printf("Please select one of the above options: "); + + HAL_UART_Receive(&huart4, buffer, sizeof(buffer), 5000); + + switch (buffer[0]) { + + case 't': + memset(&args, 0, sizeof(args)); + printf("\nCrypt Test\n"); + wolfcrypt_test(&args); + printf("Crypt Test: Return code %d\n", args.return_code); + break; + + case 'b': + memset(&args, 0, sizeof(args)); + printf("\nBenchmark Test\n"); + benchmark_test(&args); + printf("Benchmark Test: Return code %d\n", args.return_code); + break; + + case 'm': + printf("\nTPM 2.0 Test\n"); +#ifdef WOLF_TPM2 + args.return_code = TPM2_Demo(); +#endif + printf("TPM 2.0 Test: Return code %d\n", args.return_code); + break; + + // All other cases go here + default: printf("\r\nSelection out of range\r\n"); break; + } + } +} + +extern RTC_HandleTypeDef hrtc; +double current_time() +{ + RTC_TimeTypeDef time; + RTC_DateTypeDef date; + uint32_t subsec; + + /* must get time and date here due to STM32 HW bug */ + HAL_RTC_GetTime(&hrtc, &time, FORMAT_BIN); + HAL_RTC_GetDate(&hrtc, &date, FORMAT_BIN); + subsec = (255 - time.SubSeconds) * 1000 / 255; + + (void)date; + + /* return seconds.milliseconds */ + return ((double)time.Hours * 24) + + ((double)time.Minutes * 60) + + (double)time.Seconds + + ((double)subsec/1000); +} + diff --git a/IDE/OPENSTM32/include.am b/IDE/OPENSTM32/include.am new file mode 100644 index 0000000..6ff855f --- /dev/null +++ b/IDE/OPENSTM32/include.am @@ -0,0 +1,13 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + +EXTRA_DIST+= IDE/OPENSTM32/README.md +EXTRA_DIST+= IDE/OPENSTM32/.cproject +EXTRA_DIST+= IDE/OPENSTM32/.project +EXTRA_DIST+= IDE/OPENSTM32/wolfSTM32.cfg +EXTRA_DIST+= IDE/OPENSTM32/wolfSTM32.ioc +EXTRA_DIST+= IDE/OPENSTM32/wolfSTM32.xml +EXTRA_DIST+= IDE/OPENSTM32/Src/main.c +EXTRA_DIST+= IDE/OPENSTM32/Src/wolftpm_example.c +EXTRA_DIST+= IDE/OPENSTM32/Inc/wolftpm_example.h diff --git a/IDE/OPENSTM32/wolfSTM32.cfg b/IDE/OPENSTM32/wolfSTM32.cfg new file mode 100644 index 0000000..f9b02ce --- /dev/null +++ b/IDE/OPENSTM32/wolfSTM32.cfg @@ -0,0 +1,13 @@ +# This is an wolfSTM32 board with a single STM32F437IIHx chip. +# Generated by System Workbench for STM32 + +source [find interface/stlink-v2-1.cfg] + +set WORKAREASIZE 0x30000 +transport select "hla_jtag" +set CPUTAPID 0x4ba00477 + +source [find target/stm32f4x_stlink.cfg] + +# use hardware reset, connect under reset +reset_config srst_only srst_nogate diff --git a/IDE/OPENSTM32/wolfSTM32.ioc b/IDE/OPENSTM32/wolfSTM32.ioc new file mode 100644 index 0000000..d91e1d2 --- /dev/null +++ b/IDE/OPENSTM32/wolfSTM32.ioc @@ -0,0 +1,213 @@ +#MicroXplorer Configuration settings - do not modify +FREERTOS.IPParameters=Tasks01 +FREERTOS.Tasks01=defaultTask,0,128,StartDefaultTask,Default +File.Version=6 +KeepUserPlacement=false +LWIP.Version=v1.5.0_RC0_20160211_Cube +Mcu.Family=STM32F4 +Mcu.IP0=CRC +Mcu.IP1=ETH +Mcu.IP2=FREERTOS +Mcu.IP3=LWIP +Mcu.IP4=NVIC +Mcu.IP5=RCC +Mcu.IP6=RNG +Mcu.IP7=RTC +Mcu.IP8=SYS +Mcu.IP9=UART4 +Mcu.IPNb=10 +Mcu.Name=STM32F437I(G-I)Hx +Mcu.Package=UFBGA176 +Mcu.Pin0=PE2 +Mcu.Pin1=PG14 +Mcu.Pin10=PC10 +Mcu.Pin11=PC13 +Mcu.Pin12=PC14/OSC32_IN +Mcu.Pin13=PC15/OSC32_OUT +Mcu.Pin14=PH2 +Mcu.Pin15=PH0/OSC_IN +Mcu.Pin16=PH3 +Mcu.Pin17=PH1/OSC_OUT +Mcu.Pin18=PC1 +Mcu.Pin19=PC2 +Mcu.Pin2=PG13 +Mcu.Pin20=PC3 +Mcu.Pin21=PH6 +Mcu.Pin22=PA1 +Mcu.Pin23=PC4 +Mcu.Pin24=PH7 +Mcu.Pin25=PA2 +Mcu.Pin26=PC5 +Mcu.Pin27=PA7 +Mcu.Pin28=PB15 +Mcu.Pin29=VP_CRC_VS_CRC +Mcu.Pin3=PB4 +Mcu.Pin30=VP_FREERTOS_VS_ENABLE +Mcu.Pin31=VP_LWIP_VS_Enabled +Mcu.Pin32=VP_RNG_VS_RNG +Mcu.Pin33=VP_SYS_VS_tim1 +Mcu.Pin4=PB3 +Mcu.Pin5=PA15 +Mcu.Pin6=PA14 +Mcu.Pin7=PA13 +Mcu.Pin8=PG11 +Mcu.Pin9=PC11 +Mcu.PinsNb=34 +Mcu.UserConstants= +Mcu.UserName=STM32F437IIHx +MxCube.Version=4.16.1 +MxDb.Version=DB.4.0.161 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false +NVIC.ETH_IRQn=true\:0\:0\:false\:false\:true\:false +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false +NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true +NVIC.TIM1_UP_TIM10_IRQn=true\:0\:0\:false\:false\:true\:false +NVIC.TimeBase=TIM1_UP_TIM10_IRQn +NVIC.TimeBaseIP=TIM1 +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false +PA1.Mode=MII +PA1.Signal=ETH_RX_CLK +PA13.Mode=JTAG_5_pins +PA13.Signal=SYS_JTMS-SWDIO +PA14.Mode=JTAG_5_pins +PA14.Signal=SYS_JTCK-SWCLK +PA15.Mode=JTAG_5_pins +PA15.Signal=SYS_JTDI +PA2.Mode=MII +PA2.Signal=ETH_MDIO +PA7.Mode=MII +PA7.Signal=ETH_RX_DV +PB15.Mode=Reference_Clock_Detection_Activate +PB15.Signal=RTC_REFIN +PB3.Mode=JTAG_5_pins +PB3.Signal=SYS_JTDO-SWO +PB4.Mode=JTAG_5_pins +PB4.Signal=SYS_JTRST +PC1.Mode=MII +PC1.Signal=ETH_MDC +PC10.Mode=Asynchronous +PC10.Signal=UART4_TX +PC11.Mode=Asynchronous +PC11.Signal=UART4_RX +PC13.Mode=Timestamp enabled - Input Enabled to AF1 +PC13.Signal=RTC_AF1 +PC14/OSC32_IN.Mode=LSE-External-Oscillator +PC14/OSC32_IN.Signal=RCC_OSC32_IN +PC15/OSC32_OUT.Mode=LSE-External-Oscillator +PC15/OSC32_OUT.Signal=RCC_OSC32_OUT +PC2.Mode=MII +PC2.Signal=ETH_TXD2 +PC3.Mode=MII +PC3.Signal=ETH_TX_CLK +PC4.Mode=MII +PC4.Signal=ETH_RXD0 +PC5.Mode=MII +PC5.Signal=ETH_RXD1 +PCC.Checker=false +PCC.Line=STM32F427/437 +PCC.MCU=STM32F437I(G-I)Hx +PCC.MXVersion=4.16.1 +PCC.PartNumber=STM32F437IIHx +PCC.Seq0=0 +PCC.Series=STM32F4 +PCC.Temperature=25 +PCC.Vdd=null +PE2.Mode=MII +PE2.Signal=ETH_TXD3 +PG11.Mode=MII +PG11.Signal=ETH_TX_EN +PG13.Mode=MII +PG13.Signal=ETH_TXD0 +PG14.Mode=MII +PG14.Signal=ETH_TXD1 +PH0/OSC_IN.Mode=HSE-External-Oscillator +PH0/OSC_IN.Signal=RCC_OSC_IN +PH1/OSC_OUT.Mode=HSE-External-Oscillator +PH1/OSC_OUT.Signal=RCC_OSC_OUT +PH2.Mode=MII +PH2.Signal=ETH_CRS +PH3.Mode=MII +PH3.Signal=ETH_COL +PH6.Mode=MII +PH6.Signal=ETH_RXD2 +PH7.Mode=MII +PH7.Signal=ETH_RXD3 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=2 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32F437IIHx +ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.13.0 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x10000 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.PreviousToolchain=SW4STM32 +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=wolfSTM32.ioc +ProjectManager.ProjectName=wolfSTM32 +ProjectManager.StackSize=0x4000 +ProjectManager.TargetToolchain=SW4STM32 +ProjectManager.ToolChainLocation= +ProjectManager.UnderRoot=true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false,2-MX_CRC_Init-CRC-false,3-MX_RNG_Init-RNG-false,4-MX_UART4_Init-UART4-false,5-MX_LWIP_Init-LWIP-false,6-MX_RTC_Init-RTC-false +RCC.48MHZClocksFreq_Value=48000000 +RCC.AHBFreq_Value=120000000 +RCC.APB1CLKDivider=RCC_HCLK_DIV4 +RCC.APB1Freq_Value=30000000 +RCC.APB1TimFreq_Value=60000000 +RCC.APB2CLKDivider=RCC_HCLK_DIV2 +RCC.APB2Freq_Value=60000000 +RCC.APB2TimFreq_Value=120000000 +RCC.CortexFreq_Value=120000000 +RCC.EthernetFreq_Value=120000000 +RCC.FCLKCortexFreq_Value=120000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=120000000 +RCC.HSE_VALUE=25000000 +RCC.HSI_VALUE=16000000 +RCC.I2SClocksFreq_Value=160000000 +RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,PLLSourceVirtual,RCC_RTC_Clock_Source,RTCFreq_Value,RTCHSEDivFreq_Value,SAI_AClocksFreq_Value,SAI_BClocksFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAIOutputFreq_Value,VCOSAIOutputFreq_ValueQ,VcooutputI2S,VcooutputI2SQ +RCC.LSI_VALUE=32000 +RCC.MCO2PinFreq_Value=120000000 +RCC.PLLCLKFreq_Value=120000000 +RCC.PLLM=15 +RCC.PLLN=144 +RCC.PLLQ=5 +RCC.PLLQCLKFreq_Value=48000000 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.RCC_RTC_Clock_Source=RCC_RTCCLKSOURCE_LSE +RCC.RTCFreq_Value=32768 +RCC.RTCHSEDivFreq_Value=12500000 +RCC.SAI_AClocksFreq_Value=20416666.666666668 +RCC.SAI_BClocksFreq_Value=20416666.666666668 +RCC.SYSCLKFreq_VALUE=120000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.VCOI2SOutputFreq_Value=320000000 +RCC.VCOInputFreq_Value=1666666.6666666667 +RCC.VCOOutputFreq_Value=240000000 +RCC.VCOSAIOutputFreq_Value=81666666.66666667 +RCC.VCOSAIOutputFreq_ValueQ=20416666.666666668 +RCC.VcooutputI2S=160000000 +RCC.VcooutputI2SQ=160000000 +VP_CRC_VS_CRC.Mode=CRC_Activate +VP_CRC_VS_CRC.Signal=CRC_VS_CRC +VP_FREERTOS_VS_ENABLE.Mode=Enabled +VP_FREERTOS_VS_ENABLE.Signal=FREERTOS_VS_ENABLE +VP_LWIP_VS_Enabled.Mode=Enabled +VP_LWIP_VS_Enabled.Signal=LWIP_VS_Enabled +VP_RNG_VS_RNG.Mode=RNG_Activate +VP_RNG_VS_RNG.Signal=RNG_VS_RNG +VP_SYS_VS_tim1.Mode=TIM1 +VP_SYS_VS_tim1.Signal=SYS_VS_tim1 +board=wolfSTM32 diff --git a/IDE/OPENSTM32/wolfSTM32.xml b/IDE/OPENSTM32/wolfSTM32.xml new file mode 100644 index 0000000..a458809 --- /dev/null +++ b/IDE/OPENSTM32/wolfSTM32.xml @@ -0,0 +1,9 @@ + + + + wolfSTM32 + stm32f437iihx + JTAG + ST-LinkV2-1 + + diff --git a/IDE/include.am b/IDE/include.am new file mode 100644 index 0000000..a653678 --- /dev/null +++ b/IDE/include.am @@ -0,0 +1,5 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + +include IDE/OPENSTM32/include.am diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..509f297 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,102 @@ +# includes append to these: +SUFFIXES = +TESTS = +CLEANFILES = +DISTCLEANFILES = +bin_PROGRAMS = +noinst_HEADERS = +lib_LTLIBRARIES = +man_MANS = +noinst_LTLIBRARIES = +noinst_PROGRAMS = +include_HEADERS = +nobase_include_HEADERS = +check_PROGRAMS = +EXTRA_HEADERS = +BUILT_SOURCES = +EXTRA_DIST = +noinst_SCRIPTS = +check_SCRIPTS = +dist_noinst_SCRIPTS = +dist_doc_DATA = + + +#includes additional rules from aminclude.am +@INC_AMINCLUDE@ +DISTCLEANFILES+= aminclude.am + +exampledir = $(docdir)/example +dist_example_DATA= + +ACLOCAL_AMFLAGS= -I m4 + + +include src/include.am +include wolftpm/include.am +include examples/include.am +include IDE/include.am + +EXTRA_DIST+= README.md +EXTRA_DIST+= LICENSE +EXTRA_DIST+= autogen.sh + +TEST_EXTENSIONS=.test +TESTS += $(check_PROGRAMS) + +check_SCRIPTS+= $(dist_noinst_SCRIPTS) +TESTS += $(check_SCRIPTS) + +test: check + +DISTCLEANFILES+= wolftpm-config + + +maintainer-clean-local: + -rm Makefile.in + -rm aclocal.m4 + -rm build-aux/compile + -rm build-aux/config.guess + -rm build-aux/config.sub + -rm build-aux/depcomp + -rm build-aux/install-sh + -rm build-aux/ltmain.sh + -rm build-aux/missing + -rm wolftpm-config + -rmdir build-aux + -rm configure + -rm config.log + -rm config.status + -rm config.in + -rm m4/libtool.m4 + -rm m4/ltoptions.m4 + -rm m4/ltsugar.m4 + -rm m4/ltversion.m4 + -rm m4/lt~obsolete.m4 + find . -type f -name '*~' -exec rm -f '{}' \; + -rm -f @PACKAGE@-*.tar.gz + -rm -f @PACKAGE@-*.rpm + +# !!!! first line of rule has to start with a hard (real) tab, not spaces +egs: + $(MAKE) examples/mqttclient/mqttclient; + +install-exec-local: install-generic-config + +install-generic-config: + $(mkinstalldirs) $(DESTDIR)$(bindir) + $(INSTALL_SCRIPT) @GENERIC_CONFIG@ $(DESTDIR)$(bindir) + +uninstall-local: + -rm -f $(DESTDIR)$(bindir)/@GENERIC_CONFIG@ + +merge-clean: + @find ./ | $(GREP) \.gcda | xargs rm -f + @find ./ | $(GREP) \.gcno | xargs rm -f + @find ./ | $(GREP) \.gz | xargs rm -f + @find ./ | $(GREP) \.orig | xargs rm -f + @find ./ | $(GREP) \.rej | xargs rm -f + @find ./ | $(GREP) \.rpm | xargs rm -f + @find ./ | $(GREP) \.THIS | xargs rm -f + @find ./ | $(GREP) \.OTHER | xargs rm -f + @find ./ | $(GREP) \.BASE | xargs rm -f + @find ./ | $(GREP) \~$$ | xargs rm -f diff --git a/README.md b/README.md index 2410855..8c0bd46 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,160 @@ -# wolfTPM -wolfSSL TPM 2.0 +# wolfTPM (TPM 2.0) + +This example demonstrates calling the various TPM 2.0 API's. + + +## Building + +`./configure && make` + + +## Platform + +This example was written for the STM32 with the CubeMX HAL. To add additional SPI hardware support insert your own interface call in `tpm2_demo.c` for the `TPM2_IoCb` function. + + +## Sample Output + +``` +MENU + t. WolfCrypt Test + b. WolfCrypt Benchmark + m. WolfCrypt TPM 2.0 Test +Please select one of the above options: m + +TPM 2.0 Test +TPM2: Caps 0x30000697, Did 0x001b, Vid 0x15d1, Rid 0x10 +TPM2_Startup pass +TPM2_SelfTest pass +TPM2_GetTestResult: Size 10, Rc 0x0 +TPM2_IncrementalSelfTest: Rc 0x0, Alg 0x1 (Todo 0) +TPM2_GetCapability: Property FamilyIndicator 0x322e3000 +TPM2_GetCapability: Property PCR Count 24 +TPM2_GetRandom: Got 32 bytes +TPM2_PCR_Read: Index 0, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 1, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 2, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 3, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 4, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 5, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 6, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 7, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 8, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 9, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 10, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 11, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 12, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 13, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 14, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 15, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 16, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 17, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 18, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 19, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 20, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 21, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 22, Digest Sz 32, Update Counter 20 +TPM2_PCR_Read: Index 23, Digest Sz 32, Update Counter 20 +TPM 2.0 Test: Return code 0 +``` + + +### With Debug Enabled: + +``` +MENU + t. WolfCrypt Test + b. WolfCrypt Benchmark + m. WolfCrypt TPM 2.0 Test +Please select one of the above options: m + +Please select one of the above options: +TPM 2.0 Test +TPM2: Caps 0x30000697, Did 0x001b, Vid 0x15d1, Rid 0x10 +TPM2_Startup pass +TPM2_SelfTest pass +TPM2_GetTestResult: Size 10, Rc 0x0 + 00 01 f9 db 00 00 00 00 00 00 | .......... +TPM2_IncrementalSelfTest: Rc 0x0, Alg 0x1 (Todo 0) +TPM2_GetCapability: Property FamilyIndicator 0x322e3000 +TPM2_GetCapability: Property PCR Count 24 +TPM2_GetRandom: Got 32 bytes + ab 37 21 9f 63 7b 16 3a 5f 99 c2 d3 3a 64 16 ea | .7!.c{.:_...:d.. + b4 e8 5f 9e 93 f6 63 3b af da c6 a7 8a df 78 b2 | .._...c;......x. +TPM2_PCR_Read: Index 0, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 1, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 2, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 3, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 4, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 5, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 6, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 7, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 8, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 9, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 10, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 11, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 12, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 13, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 14, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 15, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 16, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 17, Digest Sz 32, Update Counter 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ +TPM2_PCR_Read: Index 18, Digest Sz 32, Update Counter 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ +TPM2_PCR_Read: Index 19, Digest Sz 32, Update Counter 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ +TPM2_PCR_Read: Index 20, Digest Sz 32, Update Counter 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ +TPM2_PCR_Read: Index 21, Digest Sz 32, Update Counter 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ +TPM2_PCR_Read: Index 22, Digest Sz 32, Update Counter 20 + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff | ................ +TPM2_PCR_Read: Index 23, Digest Sz 32, Update Counter 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ +TPM2_PCR_Read: Index 0, Digest Sz 32, Update Counter 21 + bb 22 75 c4 9f 28 ad 52 ca e6 d5 5e 34 a9 74 a5 | ."u..(.R...^4.t. + 8c 7a 3b a2 6f 97 6e 8e cb be 7a 53 69 18 dc 73 | .z;.o.n...zSi..s +TPM 2.0 Test: Return code 0 +``` diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..e82b4f6 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +# Create configure and makefile stuff... +# + +set -e + +# Git hooks should come before autoreconf. +if test -d .git; then + if ! test -d .git/hooks; then + mkdir .git/hooks + fi + ln -s -f ../../pre-commit.sh .git/hooks/pre-commit +fi + +# if get an error about libtool not setup +# " error: Libtool library used but 'LIBTOOL' is undefined +# The usual way to define 'LIBTOOL' is to add 'LT_INIT' " +# manually call libtoolize or glibtoolize before running this again +# (g)libtoolize + +# if you get an error about config.rpath missing, some buggy automake versions +# then touch the missing file (may need to make config/ first). +# touch config/config.rpath +# touch config.rpath + +if test ! -d build-aux; then + echo "Making missing build-aux directory." + mkdir -p build-aux +fi + +if test ! -f build-aux/config.rpath; then + echo "Touching missing build-aux/config.rpath file." + touch build-aux/config.rpath +fi + + +# If this is a source checkout then call autoreconf with error as well +if test -d .git; then + WARNINGS="all,error" +else + WARNINGS="all" +fi + +autoreconf --install --force --verbose diff --git a/commit-tests.sh b/commit-tests.sh new file mode 100755 index 0000000..7c26978 --- /dev/null +++ b/commit-tests.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +#commit-tests.sh + + +# make sure current config is ok +echo -e "\n\nTesting current config...\n\n" +make clean; make -j 8 test; +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "\n\nCurrent config make test failed" && exit 1 + + +# make sure basic config is ok +echo -e "\n\nTesting no TLS config too...\n\n" +./configure; +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "\n\nTest './configure' failed" && exit 1 + +make -j 8 test; +RESULT=$? +[ $RESULT -ne 0 ] && echo -e "\n\nTest './configure' make test failed " && exit 1 + + +exit 0 diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..8a5e465 --- /dev/null +++ b/configure.ac @@ -0,0 +1,143 @@ +# wolftpm +# Copyright (C) 2016 wolfSSL Inc. +# All right reserved. + +AC_INIT([wolftpm],[0.1.0],[https://github.com/wolfssl/wolfTPM/issues],[wolftpm],[http://www.wolfssl.com]) + +AC_PREREQ([2.63]) +AC_CONFIG_AUX_DIR([build-aux]) + +: ${CFLAGS=""} + +AC_CANONICAL_HOST +AC_CANONICAL_BUILD + +AM_INIT_AUTOMAKE([1.11 -Wall -Werror -Wno-portability foreign tar-ustar subdir-objects no-define color-tests]) + +AC_ARG_PROGRAM +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([src/config.h]) + +WOLFMQTT_LIBRARY_VERSION=1:0:0 +# | | | +# +------+ | +---+ +# | | | +# current:revision:age +# | | | +# | | +- increment if interfaces have been added +# | | set to zero if interfaces have been removed +# | | or changed +# | +- increment if source code has changed +# | set to zero if current is incremented +# +- increment if interfaces have been added, removed or changed +AC_SUBST([WOLFMQTT_LIBRARY_VERSION]) + +LT_PREREQ([2.2]) +LT_INIT([disable-static], [win32-dll]) +LT_LANG([C]) + +gl_VISIBILITY +AS_IF([test -n "$CFLAG_VISIBILITY"], + [AM_CPPFLAGS="$AM_CPPFLAGS $CFLAG_VISIBILITY" + CPPFLAGS="$CPPFLAGS $CFLAG_VISIBILITY"]) + +# silent +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +# Checks for programs. +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_CC_C_O +AC_PROG_INSTALL + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_SIZEOF([long long], 8) +AC_CHECK_SIZEOF([long], 4) + +# Check headers/libs +AC_CHECK_FUNCS([gethostbyname]) +AC_CHECK_FUNCS([getaddrinfo]) +AC_CHECK_FUNCS([gettimeofday]) +AC_CHECK_FUNCS([inet_ntoa]) +AC_CHECK_FUNCS([memset]) +AC_CHECK_FUNCS([socket]) +AC_CHECK_FUNCS([signal]) +AC_CHECK_LIB(network,socket) + +# DEBUG +DEBUG_CFLAGS="-g -O0" +DEBUG_CPPFLAGS="-DDEBUG -DDEBUG_WOLFMQTT" + +AX_DEBUG +AS_IF([test "x$ax_enable_debug" = "xyes"], + [AM_CFLAGS="$DEBUG_CFLAGS $AM_CFLAGS" + AM_CPPFLAGS="$DEBUG_CPPFLAGS $AM_CPPFLAGS"], + [AM_CFLAGS="$AM_CFLAGS -O2" + AM_CPPFLAGS="-DNDEBUG $AM_CFLAGS"]) + +AX_PTHREAD([AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"]) + + +# Checks for typedefs, structures, and compiler characteristics. +if test "$ac_cv_sizeof_long" = "8"; then + AM_CPPFLAGS="$AM_CPPFLAGS -DSIZEOF_LONG=8" +else + if test "$ac_cv_sizeof_long_long" = "8"; then + AM_CPPFLAGS="$AM_CPPFLAGS -DSIZEOF_LONG_LONG=8" + fi +fi + + +TAO_REQUIRE_LIBWOLFSSL +AM_CPPFLAGS="$AM_CPPFLAGS -DDHAVE_WOLFSSL_OPTIONS -DHAVE_CYASSL_OPTIONS" + + +# Examples +AC_ARG_ENABLE([examples], + [ --enable-examples Enable Examples (default: enabled)], + [ ENABLED_EXAMPLES=$enableval ], + [ ENABLED_EXAMPLES=yes ] + ) + +AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$ENABLED_EXAMPLES" = "xyes"]) + + +# HARDEN FLAGS +AX_HARDEN_CC_COMPILER_FLAGS + +CREATE_HEX_VERSION +AC_SUBST([AM_CPPFLAGS]) +AC_SUBST([AM_CFLAGS]) +AC_SUBST([AM_LDFLAGS]) + +# FINAL +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([wolftpm/version.h]) + +AX_CREATE_GENERIC_CONFIG +AX_AM_JOBSERVER([yes]) + +AC_OUTPUT + +# force make clean +echo "---" +echo "Running make clean..." +make clean >/dev/null 2>&1 +echo + +# output config summary +echo "---" +echo "Configuration summary for $PACKAGE_NAME version $VERSION" +echo "" +echo " * Installation prefix: $prefix" +echo " * System type: $host_vendor-$host_os" +echo " * Host CPU: $host_cpu" +echo " * C Compiler: $CC" +echo " * C Flags: $CFLAGS" +echo " * CPP Flags: $CPPFLAGS" +echo " * Linker Flags: $LDFLAGS" +echo " * LIB Flags: $LIB" + +echo " * Examples: $ENABLED_EXAMPLES" + diff --git a/examples/include.am b/examples/include.am new file mode 100644 index 0000000..f861c16 --- /dev/null +++ b/examples/include.am @@ -0,0 +1,4 @@ +# vim:ft=automake +# All paths should be given relative to the root + +include examples/tpm/include.am diff --git a/examples/tpm/include.am b/examples/tpm/include.am new file mode 100644 index 0000000..64f27ee --- /dev/null +++ b/examples/tpm/include.am @@ -0,0 +1,4 @@ +# vim:ft=automake +# All paths should be given relative to the root + +EXTRA_DIST+= examples/tpm/tpm2_demo.c diff --git a/examples/tpm/tpm2_demo.c b/examples/tpm/tpm2_demo.c new file mode 100644 index 0000000..e36137b --- /dev/null +++ b/examples/tpm/tpm2_demo.c @@ -0,0 +1,264 @@ +/* tpm2_demo.c + * + * Copyright (C) 2006-2017 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#include + +/* Local variables */ +static TPM2_CTX gTpm2Ctx; +#ifdef WOLFSSL_STM32_CUBEMX + extern SPI_HandleTypeDef hspi1; + #define TPM2_USER_CTX &hspi1 +#else + #define TPM2_USER_CTX NULL +#endif + +/* IO Callback */ +static TPM_RC TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, + word16 xferSz, void* userCtx) +{ +#ifdef WOLFSSL_STM32_CUBEMX + SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef*)userCtx; + HAL_StatusTypeDef status; + + __HAL_SPI_ENABLE(hspi); + status = HAL_SPI_TransmitReceive(hspi, (byte*)txBuf, rxBuf, xferSz, 5000); + __HAL_SPI_DISABLE(hspi); + if (status == HAL_OK) + return TPM_RC_SUCCESS; + +#else + /* TODO: Add your platform here for HW interface */ + (void)ctx; + (void)txBuf; + (void)rxBuf; + (void)xferSz; + (void)userCtx; + +#endif + return TPM_RC_FAILURE; +} + +#define RAND_GET_SZ 32 + +int TPM2_Demo(void) +{ + TPM_RC rc; + union { + Startup_In startup; + Shutdown_In shutdown; + SelfTest_In selfTest; + GetRandom_In getRand; + GetCapability_In cap; + IncrementalSelfTest_In incSelfTest; + PCR_Read_In pcrRead; + PCR_Extend_In pcrExtend; + CreatePrimary_In create; + EvictControl_In evict; + ReadPublic_In readPub; + StartAuthSession_In authSes; + Load_In load; + FlushContext_In flushCtx; + Unseal_In unseal; + byte maxInput[MAX_COMMAND_SIZE]; + } cmdIn; + union { + GetCapability_Out cap; + GetRandom_Out getRand; + GetTestResult_Out tr; + IncrementalSelfTest_Out incSelfTest; + PCR_Read_Out pcrRead; + CreatePrimary_Out create; + ReadPublic_Out readPub; + StartAuthSession_Out authSes; + Load_Out load; + Unseal_Out unseal; + byte maxOutput[MAX_RESPONSE_SIZE]; + } cmdOut; + int pcrCount, pcrIndex, i; + TPML_TAGGED_TPM_PROPERTY* tpmProp; + TPM_HANDLE ek; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + rc = TPM2_Init(&gTpm2Ctx, TPM2_IoCb, TPM2_USER_CTX); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_Init failed %d: %s\n", rc, TPM2_GetRCString(rc)); + return rc; + } + + + cmdIn.startup.startupType = TPM_SU_CLEAR; + rc = TPM2_Startup(&cmdIn.startup); + if (rc != TPM_RC_SUCCESS && + rc != TPM_RC_INITIALIZE /* TPM_RC_INITIALIZE = Already started */ ) { + printf("TPM2_Startup failed %d: %s\n", rc, TPM2_GetRCString(rc)); + return rc; + } + printf("TPM2_Startup pass\n"); + + + /* Full self test */ + cmdIn.selfTest.fullTest = YES; + rc = TPM2_SelfTest(&cmdIn.selfTest); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_SelfTest failed %d: %s\n", rc, TPM2_GetRCString(rc)); + return rc; + } + printf("TPM2_SelfTest pass\n"); + + /* Get Test Result */ + rc = TPM2_GetTestResult(&cmdOut.tr); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_GetTestResult failed %d: %s\n", rc, TPM2_GetRCString(rc)); + return rc; + } + printf("TPM2_GetTestResult: Size %d, Rc 0x%x\n", cmdOut.tr.outData.size, + cmdOut.tr.testResult); + WOLFSSL_BUFFER(cmdOut.tr.outData.buffer, cmdOut.tr.outData.size); + + /* Incremental Test */ + cmdIn.incSelfTest.toTest.count = 1; + cmdIn.incSelfTest.toTest.algorithms[0] = TPM_ALG_RSA; + rc = TPM2_IncrementalSelfTest(&cmdIn.incSelfTest, &cmdOut.incSelfTest); + printf("TPM2_IncrementalSelfTest: Rc 0x%x, Alg 0x%x (Todo %d)\n", + rc, cmdIn.incSelfTest.toTest.algorithms[0], + (int)cmdOut.incSelfTest.toDoList.count); + + + /* Get Capability for Property */ + cmdIn.cap.capability = TPM_CAP_TPM_PROPERTIES; + cmdIn.cap.property = TPM_PT_FAMILY_INDICATOR; + cmdIn.cap.propertyCount = 1; + rc = TPM2_GetCapability(&cmdIn.cap, &cmdOut.cap); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_GetCapability failed %d: %s\n", rc, TPM2_GetRCString(rc)); + return rc; + } + tpmProp = &cmdOut.cap.capabilityData.data.tpmProperties; + printf("TPM2_GetCapability: Property FamilyIndicator 0x%08x\n", + (unsigned int)tpmProp->tpmProperty[0].value); + + cmdIn.cap.capability = TPM_CAP_TPM_PROPERTIES; + cmdIn.cap.property = TPM_PT_PCR_COUNT; + cmdIn.cap.propertyCount = 1; + rc = TPM2_GetCapability(&cmdIn.cap, &cmdOut.cap); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_GetCapability failed %d: %s\n", rc, TPM2_GetRCString(rc)); + return rc; + } + tpmProp = &cmdOut.cap.capabilityData.data.tpmProperties; + pcrCount = tpmProp->tpmProperty[0].value; + printf("TPM2_GetCapability: Property PCR Count %d\n", pcrCount); + + + /* Random */ + cmdIn.getRand.bytesRequested = RAND_GET_SZ; + rc = TPM2_GetRandom(&cmdIn.getRand, &cmdOut.getRand); + if (rc != TPM_RC_SUCCESS) { + printf("TPM2_GetRandom failed %d: %s\n", rc, TPM2_GetRCString(rc)); + return rc; + } + if (cmdOut.getRand.randomBytes.size != RAND_GET_SZ) { + printf("TPM2_GetRandom length mismatch %d != %d\n", + cmdOut.getRand.randomBytes.size, RAND_GET_SZ); + return rc; + } + printf("TPM2_GetRandom: Got %d bytes\n", cmdOut.getRand.randomBytes.size); + WOLFSSL_BUFFER(cmdOut.getRand.randomBytes.buffer, + cmdOut.getRand.randomBytes.size); + + + /* PCR Read */ + for (i=0; i +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 9 + +AC_DEFUN([AX_ADD_AM_MACRO],[ + AC_REQUIRE([AX_AM_MACROS]) + AX_APPEND_TO_FILE([$AMINCLUDE],[$1]) +]) diff --git a/m4/ax_am_jobserver.m4 b/m4/ax_am_jobserver.m4 new file mode 100644 index 0000000..0bee7ab --- /dev/null +++ b/m4/ax_am_jobserver.m4 @@ -0,0 +1,55 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_am_jobserver.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_AM_JOBSERVER([default_value]) +# +# DESCRIPTION +# +# Enables the use of make's jobserver for the purpose of parallel building +# by passing the -j option to make. +# +# The option --enable-jobserver is added to configure which can accept a +# yes, no, or an integer. The integer is the number of separate jobs to +# allow. If 'yes' is given, then the is assumed to be one more than the +# number of CPUs (determined through AX_COUNT_CPUS). If the value of no is +# given, then the jobserver is disabled. The default value is given by the +# first argument of the macro, or 'yes' if the argument is omitted. +# +# This macro makes use of AX_AM_MACROS, so you must add the following line +# +# @INC_AMINCLUDE@ +# +# to your Makefile.am files. +# +# LICENSE +# +# Copyright (c) 2008 Michael Paul Bailey +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AC_DEFUN([AX_AM_JOBSERVER], [ + AC_REQUIRE([AX_COUNT_CPUS]) + AC_REQUIRE([AX_AM_MACROS]) + AC_ARG_ENABLE( jobserver, + [ --enable-jobserver@<:@=no/yes/@%:@@:>@ default=m4_ifval([$1],[$1],[yes]) + Enable up to @%:@ make jobs + yes: enable one more than CPU count + ],, [enable_jobserver=m4_ifval([$1],[$1],[yes])]) + if test "x$enable_jobserver" = "xyes"; then + enable_jobserver=$CPU_COUNT + ((enable_jobserver++)) + fi + m4_pattern_allow(AM_MAKEFLAGS) + if test "x$enable_jobserver" != "xno"; then + AC_MSG_NOTICE([added jobserver support to make for $enable_jobserver jobs]) + AX_ADD_AM_MACRO( AM_MAKEFLAGS += -j$enable_jobserver ) + fi +]) diff --git a/m4/ax_am_macros.m4 b/m4/ax_am_macros.m4 new file mode 100644 index 0000000..6b4bd22 --- /dev/null +++ b/m4/ax_am_macros.m4 @@ -0,0 +1,44 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_am_macros.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_AM_MACROS +# +# DESCRIPTION +# +# Adds support for macros that create Make rules. You must manually add +# the following line +# +# @INC_AMINCLUDE@ +# +# to your Makefile.in (or Makefile.am if you use Automake) files. +# +# LICENSE +# +# Copyright (c) 2009 Tom Howard +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 9 + +AC_DEFUN([AX_AM_MACROS], +[ +AC_MSG_NOTICE([adding automake macro support]) +AMINCLUDE="aminclude.am" +AC_SUBST(AMINCLUDE) +AC_MSG_NOTICE([creating $AMINCLUDE]) +AMINCLUDE_TIME=`date` +AX_PRINT_TO_FILE([$AMINCLUDE],[[ +# generated automatically by configure from AX_AUTOMAKE_MACROS +# on $AMINCLUDE_TIME + +]]) + +INC_AMINCLUDE="include \$(top_builddir)/$AMINCLUDE" +AC_SUBST(INC_AMINCLUDE) +]) diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4 new file mode 100644 index 0000000..1f8e708 --- /dev/null +++ b/m4/ax_append_compile_flags.m4 @@ -0,0 +1,65 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# For every FLAG1, FLAG2 it is checked whether the compiler works with the +# flag. If it does, the flag is added FLAGS-VARIABLE +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. During the check the flag is always added to the +# current language's flags. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# NOTE: This macro depends on the AX_APPEND_FLAG and +# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with +# AX_APPEND_LINK_FLAGS. +# +# LICENSE +# +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 3 + +AC_DEFUN([AX_APPEND_COMPILE_FLAGS], +[AC_REQUIRE([AX_CHECK_COMPILE_FLAG]) +AC_REQUIRE([AX_APPEND_FLAG]) +for flag in $1; do + AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3]) +done +])dnl AX_APPEND_COMPILE_FLAGS diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 new file mode 100644 index 0000000..1d38b76 --- /dev/null +++ b/m4/ax_append_flag.m4 @@ -0,0 +1,69 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# +# DESCRIPTION +# +# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space +# added in between. +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains +# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly +# FLAG. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_APPEND_FLAG], +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl +AS_VAR_SET_IF(FLAGS, + [case " AS_VAR_GET(FLAGS) " in + *" $1 "*) + AC_RUN_LOG([: FLAGS already contains $1]) + ;; + *) + AC_RUN_LOG([: FLAGS="$FLAGS $1"]) + AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) + ;; + esac], + [AS_VAR_SET(FLAGS,["$1"])]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG diff --git a/m4/ax_append_link_flags.m4 b/m4/ax_append_link_flags.m4 new file mode 100644 index 0000000..48cbd4b --- /dev/null +++ b/m4/ax_append_link_flags.m4 @@ -0,0 +1,63 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# For every FLAG1, FLAG2 it is checked whether the linker works with the +# flag. If it does, the flag is added FLAGS-VARIABLE +# +# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is +# used. During the check the flag is always added to the linker's flags. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG. +# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS. +# +# LICENSE +# +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 3 + +AC_DEFUN([AX_APPEND_LINK_FLAGS], +[AC_REQUIRE([AX_CHECK_LINK_FLAG]) +AC_REQUIRE([AX_APPEND_FLAG]) +for flag in $1; do + AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3]) +done +])dnl AX_APPEND_LINK_FLAGS diff --git a/m4/ax_append_to_file.m4 b/m4/ax_append_to_file.m4 new file mode 100644 index 0000000..f9f54e0 --- /dev/null +++ b/m4/ax_append_to_file.m4 @@ -0,0 +1,27 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_to_file.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_TO_FILE([FILE],[DATA]) +# +# DESCRIPTION +# +# Appends the specified data to the specified file. +# +# LICENSE +# +# Copyright (c) 2008 Tom Howard +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +AC_DEFUN([AX_APPEND_TO_FILE],[ +AC_REQUIRE([AX_FILE_ESCAPES]) +printf "$2\n" >> "$1" +]) diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000..c3a8d69 --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,72 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 new file mode 100644 index 0000000..e2d0d36 --- /dev/null +++ b/m4/ax_check_link_flag.m4 @@ -0,0 +1,71 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/ax_count_cpus.m4 b/m4/ax_count_cpus.m4 new file mode 100644 index 0000000..d4f3d29 --- /dev/null +++ b/m4/ax_count_cpus.m4 @@ -0,0 +1,57 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_count_cpus.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COUNT_CPUS +# +# DESCRIPTION +# +# Attempt to count the number of processors present on the machine. If the +# detection fails, then a value of 1 is assumed. +# +# The value is placed in the CPU_COUNT variable. +# +# LICENSE +# +# Copyright (c) 2012 Brian Aker +# Copyright (c) 2008 Michael Paul Bailey +# Copyright (c) 2008 Christophe Tournayre +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 10 + + AC_DEFUN([AX_COUNT_CPUS],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_PROG_EGREP]) + AC_MSG_CHECKING([the number of available CPUs]) + CPU_COUNT="0" + + AS_CASE([$host_os],[ + *darwin*],[ + AS_IF([test -x /usr/sbin/sysctl],[ + sysctl_a=`/usr/sbin/sysctl -a 2>/dev/null| grep -c hw.cpu` + AS_IF([test sysctl_a],[ + CPU_COUNT=`/usr/sbin/sysctl -n hw.ncpu` + ]) + ])],[ + *linux*],[ + AS_IF([test "x$CPU_COUNT" = "x0" -a -e /proc/cpuinfo],[ + AS_IF([test "x$CPU_COUNT" = "x0" -a -e /proc/cpuinfo],[ + CPU_COUNT=`$EGREP -c '^processor' /proc/cpuinfo` + ]) + ]) + ]) + + AS_IF([test "x$CPU_COUNT" = "x0"],[ + CPU_COUNT="1" + AC_MSG_RESULT( [unable to detect (assuming 1)] ) + ],[ + AC_MSG_RESULT( $CPU_COUNT ) + ]) + ]) diff --git a/m4/ax_create_generic_config.m4 b/m4/ax_create_generic_config.m4 new file mode 100644 index 0000000..535838f --- /dev/null +++ b/m4/ax_create_generic_config.m4 @@ -0,0 +1,195 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_create_generic_config.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CREATE_GENERIC_CONFIG [(PACKAGEnlibs [, VERSION])] +# +# DESCRIPTION +# +# Creates a generic PACKAGE-config file that has all the things that you +# want, hmm, well, atleast it has --cflags, --version, --libs. Ahhm, did +# you see ax_path_generic in the autoconf-archive? ;-) +# +# this macros saves you all the typing for a pkg-config.in script, you +# don't even need to distribute one along. Place this macro in your +# configure.ac, et voila, you got one that you want to install. +# +# oh, btw, if the first arg looks like "mylib -lwhat' then it will go to +# be added to the --libs, and mylib is extracted. +# +# the defaults: $1 = $PACKAGE $LIBS $2 = $VERSION there is also an +# AC_SUBST(GENERIC_CONFIG) that will be set to the name of the file that +# we did output in this macro. Use as: +# +# install-exec-local: install-generic-config +# +# install-generic-config: +# $(mkinstalldirs) $(DESTDIR)$(bindir) +# $(INSTALL_SCRIPT) @GENERIC_CONFIG@ $(DESTDIR)$(bindir) +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 6 + +AU_ALIAS([AC_CREATE_GENERIC_CONFIG], [AX_CREATE_GENERIC_CONFIG]) +AC_DEFUN([AX_CREATE_GENERIC_CONFIG],[# create a generic PACKAGE-config file +L=`echo ifelse($1, , $PACKAGE $LIBS, $1)` +P=`echo $L | sed -e 's/ -.*//'` +P=`echo $P` +V=`echo ifelse($2, , $VERSION, $2)` +F=`echo $P-config` +L=`echo -l$L | sed -e 's/^-llib/-l/'` +AC_MSG_RESULT(creating $F - generic $V for $L) +test "x$prefix" = xNONE && prefix="$ac_default_prefix" +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' +echo '#! /bin/sh' >$F +echo ' ' >>$F +echo 'package="'$P'"' >>$F +echo 'version="'$V'"' >>$F +echo 'libs="'$L'"' >>$F +echo ' ' >>$F +# in the order of occurence a standard automake Makefile +echo 'prefix="'$prefix'"' >>$F +echo 'exec_prefix="'$exec_prefix'"' >>$F +echo 'bindir="'$bindir'"' >>$F +echo 'sbindir="'$sbindir'"' >>$F +echo 'libexecdir="'$libexecdir'"' >>$F +echo 'datadir="'$datadir'"' >>$F +echo 'sysconfdir="'$sysconfdir'"' >>$F +echo 'sharedstatedir="'$sharedstatedir'"' >>$F +echo 'localstatedir="'$localstatedir'"' >>$F +echo 'libdir="'$libdir'"' >>$F +echo 'infodir="'$infodir'"' >>$F +echo 'mandir="'$mandir'"' >>$F +echo 'includedir="'$includedir'"' >>$F +echo 'target="'$target'"' >>$F +echo 'host="'$host'"' >>$F +echo 'build="'$build'"' >>$F +echo ' ' >>$F +echo 'if test "'"\$""#"'" -eq 0; then' >>$F +echo ' cat <>$F +echo 'Usage: $package-config [OPTIONS]' >>$F +echo 'Options:' >>$F +echo ' --prefix[=DIR]) : \$prefix' >>$F +echo ' --package) : \$package' >>$F +echo ' --version) : \$version' >>$F +echo ' --cflags) : -I\$includedir' >>$F +echo ' --libs) : -L\$libdir -l\$package' >>$F +echo ' --help) print all the options (not just these)' >>$F +echo 'EOF' >>$F +echo 'fi' >>$F +echo ' ' >>$F +echo 'o=""' >>$F +echo 'h=""' >>$F +echo 'for i in "[$]@"; do' >>$F +echo ' case $i in' >>$F +echo ' --prefix=*) prefix=`echo $i | sed -e "s/--prefix=//"` ;;' >>$F +echo ' --prefix) o="$o $prefix" ;;' >>$F +echo ' --package) o="$o $package" ;;' >>$F +echo ' --version) o="$o $version" ;;' >>$F +echo ' --cflags) if test "_$includedir" != "_/usr/include"' >>$F +echo ' then o="$o -I$includedir" ; fi' >>$F +echo ' ;;' >>$F +echo ' --libs) o="$o -L$libdir $libs" ;;' >>$F +echo ' --exec_prefix|--eprefix) o="$o $exec_prefix" ;;' >>$F +echo ' --bindir) o="$o $bindir" ;;' >>$F +echo ' --sbindir) o="$o $sbindir" ;;' >>$F +echo ' --libexecdir) o="$o $libexecdir" ;;' >>$F +echo ' --datadir) o="$o $datadir" ;;' >>$F +echo ' --datainc) o="$o -I$datadir" ;;' >>$F +echo ' --datalib) o="$o -L$datadir" ;;' >>$F +echo ' --sysconfdir) o="$o $sysconfdir" ;;' >>$F +echo ' --sharedstatedir) o="$o $sharedstatedir" ;;' >>$F +echo ' --localstatedir) o="$o $localstatedir" ;;' >>$F +echo ' --libdir) o="$o $libdir" ;;' >>$F +echo ' --libadd) o="$o -L$libdir" ;;' >>$F +echo ' --infodir) o="$o $infodir" ;;' >>$F +echo ' --mandir) o="$o $mandir" ;;' >>$F +echo ' --target) o="$o $target" ;;' >>$F +echo ' --host) o="$o $host" ;;' >>$F +echo ' --build) o="$o $build" ;;' >>$F +echo ' --data) o="$o -I$datadir/$package" ;;' >>$F +echo ' --pkgdatadir) o="$o $datadir/$package" ;;' >>$F +echo ' --pkgdatainc) o="$o -I$datadir/$package" ;;' >>$F +echo ' --pkgdatalib) o="$o -L$datadir/$package" ;;' >>$F +echo ' --pkglibdir) o="$o $libdir/$package" ;;' >>$F +echo ' --pkglibinc) o="$o -I$libinc/$package" ;;' >>$F +echo ' --pkglibadd) o="$o -L$libadd/$package" ;;' >>$F +echo ' --pkgincludedir) o="$o $includedir/$package" ;;' >>$F +echo ' --help) h="1" ;;' >>$F +echo ' -?//*|-?/*//*|-?./*//*|//*|/*//*|./*//*) ' >>$F +echo ' v=`echo $i | sed -e s://:\$:g`' >>$F +echo ' v=`eval "echo $v"` ' >>$F +echo ' o="$o $v" ;; ' >>$F +echo ' esac' >>$F +echo 'done' >>$F +echo ' ' >>$F +echo 'o=`eval "echo $o"`' >>$F +echo 'o=`eval "echo $o"`' >>$F +echo 'eval "echo $o"' >>$F +echo ' ' >>$F +echo 'if test ! -z "$h" ; then ' >>$F +echo 'cat <>$F +echo ' --prefix=xxx) (what is that for anyway?)' >>$F +echo ' --prefix) \$prefix $prefix' >>$F +echo ' --package) \$package $package' >>$F +echo ' --version) \$version $version' >>$F +echo ' --cflags) -I\$includedir unless it is /usr/include' >>$F +echo ' --libs) -L\$libdir -l\$PACKAGE \$LIBS' >>$F +echo ' --exec_prefix) or... ' >>$F +echo ' --eprefix) \$exec_prefix $exec_prefix' >>$F +echo ' --bindir) \$bindir $bindir' >>$F +echo ' --sbindir) \$sbindir $sbindir' >>$F +echo ' --libexecdir) \$libexecdir $libexecdir' >>$F +echo ' --datadir) \$datadir $datadir' >>$F +echo ' --sysconfdir) \$sysconfdir $sysconfdir' >>$F +echo ' --sharedstatedir) \$sharedstatedir$sharedstatedir' >>$F +echo ' --localstatedir) \$localstatedir $localstatedir' >>$F +echo ' --libdir) \$libdir $libdir' >>$F +echo ' --infodir) \$infodir $infodir' >>$F +echo ' --mandir) \$mandir $mandir' >>$F +echo ' --target) \$target $target' >>$F +echo ' --host) \$host $host' >>$F +echo ' --build) \$build $build' >>$F +echo ' --data) -I\$datadir/\$package' >>$F +echo ' --pkgdatadir) \$datadir/\$package' >>$F +echo ' --pkglibdir) \$libdir/\$package' >>$F +echo ' --pkgincludedir) \$includedir/\$package' >>$F +echo ' --help) generated by ax_create_generic_config.m4' >>$F +echo ' -I//varname and other inc-targets like --pkgdatainc supported' >>$F +echo ' -L//varname and other lib-targets, e.g. --pkgdatalib or --libadd' >>$F +echo 'EOF' >>$F +echo 'fi' >>$F +GENERIC_CONFIG="$F" +AC_SUBST(GENERIC_CONFIG) +]) diff --git a/m4/ax_debug.m4 b/m4/ax_debug.m4 new file mode 100644 index 0000000..94e4c9c --- /dev/null +++ b/m4/ax_debug.m4 @@ -0,0 +1,63 @@ +# =========================================================================== +# https://github.com/BrianAker/ddm4/ +# =========================================================================== +# +# SYNOPSIS +# +# AX_DEBUG() +# +# DESCRIPTION +# +# --enable-debug +# +# LICENSE +# +# Copyright (C) 2012 Brian Aker +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# +# * The names of its contributors may not be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#serial 6.1 + +AC_DEFUN([AX_DEBUG], + [AC_PREREQ([2.63])dnl + AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [Add debug code/turns off optimizations (yes|no) @<:@default=no@:>@])], + [ax_enable_debug=$enableval], + [ax_enable_debug=no]) + + AS_IF([test "x$ax_enable_debug" = xyes], + [AC_DEFINE([DEBUG],[1],[Define to 1 to enable debugging code.])], + [AC_SUBST([MCHECK]) + AC_DEFINE([DEBUG],[0],[Define to 1 to enable debugging code.])]) + + AC_MSG_CHECKING([for debug]) + AC_MSG_RESULT([$ax_enable_debug]) + AM_CONDITIONAL([DEBUG],[test "x${ax_enable_debug}" = xyes])]) diff --git a/m4/ax_file_escapes.m4 b/m4/ax_file_escapes.m4 new file mode 100644 index 0000000..f4c6a06 --- /dev/null +++ b/m4/ax_file_escapes.m4 @@ -0,0 +1,30 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_file_escapes.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_FILE_ESCAPES +# +# DESCRIPTION +# +# Writes the specified data to the specified file. +# +# LICENSE +# +# Copyright (c) 2008 Tom Howard +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AC_DEFUN([AX_FILE_ESCAPES],[ +AX_DOLLAR="\$" +AX_SRB="\\135" +AX_SLB="\\133" +AX_BS="\\\\" +AX_DQ="\"" +]) diff --git a/m4/ax_harden_compiler_flags.m4 b/m4/ax_harden_compiler_flags.m4 new file mode 100644 index 0000000..6f01c1a --- /dev/null +++ b/m4/ax_harden_compiler_flags.m4 @@ -0,0 +1,236 @@ +# =========================================================================== +# https://github.com/BrianAker/ddm4/ +# =========================================================================== +# +# SYNOPSIS +# +# AX_HARDEN_COMPILER_FLAGS() +# AX_HARDEN_LINKER_FLAGS() +# AX_HARDEN_CC_COMPILER_FLAGS() +# AX_HARDEN_CXX_COMPILER_FLAGS() +# +# DESCRIPTION +# +# Any compiler flag that "hardens" or tests code. C99 is assumed. +# +# NOTE: Implementation based on AX_APPEND_FLAG. +# +# LICENSE +# +# Copyright (C) 2012 Brian Aker +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# +# * The names of its contributors may not be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# The Following flags are not checked for +# -Wdeclaration-after-statement is counter to C99 +# AX_APPEND_COMPILE_FLAGS([-std=c++11]) -- Not ready yet +# AX_APPEND_COMPILE_FLAGS([-pedantic]) -- ? +# AX_APPEND_COMPILE_FLAGS([-Wstack-protector]) -- Issues on 32bit compile +# AX_APPEND_COMPILE_FLAGS([-fstack-protector-all]) -- Issues on 32bit compile +# AX_APPEND_COMPILE_FLAGS([-Wlong-long]) -- Don't turn on for compatibility issues memcached_stat_st +# AX_APPEND_COMPILE_FLAGS([-Wold-style-definition],,[$ax_append_compile_cflags_extra]) +# AX_APPEND_COMPILE_FLAGS([-std=c99],,[$ax_append_compile_cflags_extra]) +# AX_APPEND_COMPILE_FLAGS([-Wlogical-op],,[$ax_append_compile_cflags_extra]) +# AX_APPEND_COMPILE_FLAGS([-fstack-check],,[$ax_append_compile_cflags_extra]) -- problems with fastmath stack size checks +# AX_APPEND_COMPILE_FLAGS([-floop-parallelize-all],,[$ax_append_compile_cflags_extra]) -- causes RSA verify problem on x64 + +#serial 4 + + AC_DEFUN([AX_HARDEN_LINKER_FLAGS], [ + AC_REQUIRE([AX_CHECK_LINK_FLAG]) + AC_REQUIRE([AX_VCS_CHECKOUT]) + AC_REQUIRE([AX_DEBUG]) + + dnl If we are inside of VCS we append -Werror, otherwise we just use it to test other flags + AX_HARDEN_LIB= + ax_append_compile_link_flags_extra= + AS_IF([test "x$ac_cv_vcs_checkout" = "xyes"],[ + AX_CHECK_LINK_FLAG([-Werror],[ + AX_HARDEN_LIB="-Werror $AX_HARDEN_LIB" + ]) + ],[ + AX_CHECK_LINK_FLAG([-Werror],[ + ax_append_compile_link_flags_extra='-Werror' + ]) + ]) + + AX_CHECK_LINK_FLAG([-z relro -z now],[ + AX_HARDEN_LIB="-z relro -z now $AX_HARDEN_LIB" + ],,[$ax_append_compile_link_flags_extra]) + + AX_CHECK_LINK_FLAG([-pie],[ + AX_HARDEN_LIB="-pie $AX_HARDEN_LIB" + ],,[$ax_append_compile_link_flags_extra]) + + LIB="$LIB $AX_HARDEN_LIB" + ]) + + AC_DEFUN([AX_HARDEN_CC_COMPILER_FLAGS], [ + AC_REQUIRE([AX_APPEND_COMPILE_FLAGS]) + AC_REQUIRE([AX_HARDEN_LINKER_FLAGS]) + + AC_LANG_PUSH([C]) + + CFLAGS= + ac_cv_warnings_as_errors=no + ax_append_compile_cflags_extra= + AS_IF([test "$ac_cv_vcs_checkout" = "yes"],[ + AX_APPEND_COMPILE_FLAGS([-Werror]) + ac_cv_warnings_as_errors=yes + ],[ + AX_APPEND_COMPILE_FLAGS([-Werror],[ax_append_compile_cflags_extra]) + ]) + + AS_IF([test "$ax_enable_debug" = "yes"], [ + AX_APPEND_COMPILE_FLAGS([-g]) + AX_APPEND_COMPILE_FLAGS([-ggdb],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-O0],,[$ax_append_compile_cflags_extra]) + ],[]) + + AX_APPEND_COMPILE_FLAGS([-Wno-pragmas],,[$ax_append_compile_cflags_extra]) + + AX_APPEND_COMPILE_FLAGS([-Wall],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wno-strict-aliasing],,,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wextra],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunknown-pragmas],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wthis-test-should-fail],,[$ax_append_compile_cflags_extra]) + dnl Anything below this comment please keep sorted. + AS_IF([test "$CC" = "clang"],[],[ + AX_APPEND_COMPILE_FLAGS([--param=ssp-buffer-size=1],,[$ax_append_compile_cflags_extra]) + ]) + AX_APPEND_COMPILE_FLAGS([-Waddress],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Warray-bounds],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wbad-function-cast],,[$ax_append_compile_cflags_extra]) + dnl Not in use -Wc++-compat + AX_APPEND_COMPILE_FLAGS([-Wchar-subscripts],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wcomment],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wfloat-equal],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wformat-security],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wformat=2],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wmaybe-uninitialized],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wmissing-field-initializers],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wmissing-noreturn],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wmissing-prototypes],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wnested-externs],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wnormalized=id],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Woverride-init],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wpointer-arith],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wpointer-sign],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wredundant-decls],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wshadow],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wshorten-64-to-32],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wsign-compare],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wstrict-overflow=1],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wstrict-prototypes],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wswitch-enum],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wundef],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunused],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunused-result],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunused-variable],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wwrite-strings],,[$ax_append_compile_cflags_extra]) + AX_APPEND_COMPILE_FLAGS([-fwrapv],,[$ax_append_compile_cflags_extra]) + AC_LANG_POP + ]) + + AC_DEFUN([AX_HARDEN_CXX_COMPILER_FLAGS], [ + AC_REQUIRE([AX_HARDEN_CC_COMPILER_FLAGS]) + AC_LANG_PUSH([C++]) + + ax_append_compile_cxxflags_extra= + AS_IF([test "$ac_cv_warnings_as_errors" = "yes"],[ + AX_APPEND_COMPILE_FLAGS([-Werror]) + ],[ + AX_APPEND_COMPILE_FLAGS([-Werror],[ax_append_compile_cxxflags_extra]) + ]) + + AS_IF([test "$ax_enable_debug" = "yes" ], [ + AX_APPEND_COMPILE_FLAGS([-g],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-O0],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-ggdb],,[$ax_append_compile_cxxflags_extra]) + ],[ + AX_APPEND_COMPILE_FLAGS([-D_FORTIFY_SOURCE=2],,[$ax_append_compile_cxxflags_extra]) + ]) + + AS_IF([test "$ac_cv_vcs_checkout" = "yes" ], [ + AX_APPEND_COMPILE_FLAGS([-Werror],,[$ax_append_compile_cxxflags_extra]) + ],[ + AX_APPEND_COMPILE_FLAGS([-Wno-pragmas],,[$ax_append_compile_cxxflags_extra]) + ]) + + AX_APPEND_COMPILE_FLAGS([-Wall],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wno-strict-aliasing],,,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wextra],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunknown-pragmas],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wthis-test-should-fail],,[$ax_append_compile_cxxflags_extra]) + dnl Anything below this comment please keep sorted. + AX_APPEND_COMPILE_FLAGS([--param=ssp-buffer-size=1],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Waddress],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Warray-bounds],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wchar-subscripts],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wcomment],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wctor-dtor-privacy],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wfloat-equal],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wformat=2],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wmaybe-uninitialized],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wmissing-field-initializers],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wmissing-noreturn],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wnon-virtual-dtor],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wnormalized=id],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Woverloaded-virtual],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wpointer-arith],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wredundant-decls],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wshadow],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wshorten-64-to-32],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wsign-compare],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wstrict-overflow=1],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wswitch-enum],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wundef],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wc++11-compat],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunused],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunused-result],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wunused-variable],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wwrite-strings],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-Wformat-security],,[$ax_append_compile_cxxflags_extra]) + AX_APPEND_COMPILE_FLAGS([-fwrapv],,[$ax_append_compile_cxxflags_extra]) + AC_LANG_POP + ]) + + AC_DEFUN([AX_HARDEN_COMPILER_FLAGS], [ + AC_REQUIRE([AX_HARDEN_CXX_COMPILER_FLAGS]) + ]) + + AC_DEFUN([AX_CC_OTHER_FLAGS], [ + AC_REQUIRE([AX_APPEND_COMPILE_FLAGS]) + AC_REQUIRE([AX_HARDEN_CC_COMPILER_FLAGS]) + + AC_LANG_PUSH([C]) + AX_APPEND_COMPILE_FLAGS([-pipe],,[$ax_append_compile_cflags_extra]) + AC_LANG_POP + ]) diff --git a/m4/ax_print_to_file.m4 b/m4/ax_print_to_file.m4 new file mode 100644 index 0000000..5b9d1c3 --- /dev/null +++ b/m4/ax_print_to_file.m4 @@ -0,0 +1,27 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_print_to_file.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PRINT_TO_FILE([FILE],[DATA]) +# +# DESCRIPTION +# +# Writes the specified data to the specified file. +# +# LICENSE +# +# Copyright (c) 2008 Tom Howard +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AC_DEFUN([AX_PRINT_TO_FILE],[ +AC_REQUIRE([AX_FILE_ESCAPES]) +printf "$2" > "$1" +]) diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 new file mode 100644 index 0000000..bdb34b0 --- /dev/null +++ b/m4/ax_pthread.m4 @@ -0,0 +1,320 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 20 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) + AC_MSG_RESULT($ax_pthread_ok) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + AC_REQUIRE([WOLFSSL_DARWIN_USING_CLANG]) + AS_IF([test x"$wolfssl_darwin_clang" = x"yes"], + [ax_pthread_flags="$ax_pthread_flags"], + [ax_pthread_flags="-pthread $ax_pthread_flags"]) + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($ax_pthread_ok) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + ax_cv_PTHREAD_PRIO_INHERIT, [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != xyes; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/m4/ax_vcs_checkout.m4 b/m4/ax_vcs_checkout.m4 new file mode 100644 index 0000000..8047b65 --- /dev/null +++ b/m4/ax_vcs_checkout.m4 @@ -0,0 +1,75 @@ +# =========================================================================== +# http:// +# =========================================================================== +# +# SYNOPSIS +# +# AX_VCS_CHECKOUT +# +# DESCRIPTION +# +# Discover whether or not we are operating with a tree which +# has been checked out of a version control system. +# +# +# LICENSE +# +# Copyright (C) 2012 Brian Aker +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# +# * The names of its contributors may not be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#serial 6 + +AC_DEFUN([AX_VCS_SYSTEM], + [AC_PREREQ([2.63])dnl + AC_CACHE_CHECK([for vcs system], [ac_cv_vcs_system], + [ac_cv_vcs_system="none" + AS_IF([test -d ".bzr"],[ac_cv_vcs_system="bazaar"]) + AS_IF([test -d ".svn"],[ac_cv_vcs_system="svn"]) + AS_IF([test -d ".hg"],[ac_cv_vcs_system="mercurial"]) + AS_IF([test -d ".git"],[ac_cv_vcs_system="git"]) + ]) + AC_DEFINE_UNQUOTED([VCS_SYSTEM],["$ac_cv_vcs_system"],[VCS system]) + ]) + +AC_DEFUN([AX_VCS_CHECKOUT], + [AC_PREREQ([2.63])dnl + AC_REQUIRE([AX_VCS_SYSTEM]) + AC_CACHE_CHECK([for vcs checkout],[ac_cv_vcs_checkout], + [AS_IF([test "x$ac_cv_vcs_system" != "xnone"], + [ac_cv_vcs_checkout=yes], + [ac_cv_vcs_checkout=no]) + ]) + + AM_CONDITIONAL([IS_VCS_CHECKOUT],[test "x$ac_cv_vcs_checkout" = "xyes"]) + AS_IF([test "x$ac_cv_vcs_checkout" = "xyes"], + [AC_DEFINE([VCS_CHECKOUT],[1],[Define if the code was built from VCS.])], + [AC_DEFINE([VCS_CHECKOUT],[0],[Define if the code was built from VCS.])]) + ]) diff --git a/m4/have_wolfssl.m4 b/m4/have_wolfssl.m4 new file mode 100644 index 0000000..fbd398d --- /dev/null +++ b/m4/have_wolfssl.m4 @@ -0,0 +1,57 @@ + +#-------------------------------------------------------------------- +# Check for libwolfssl +#-------------------------------------------------------------------- + + +AC_DEFUN([_TAO_SEARCH_LIBWOLFSSL],[ + AC_REQUIRE([AC_LIB_PREFIX]) + + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lwolfssl" + + AC_LIB_HAVE_LINKFLAGS(wolfssl,, + [ + #include + ],[ + wolfSSL_Init(); + ]) + + AM_CONDITIONAL(HAVE_LIBWOLFSSL, [test "x${ac_cv_libwolfssl}" = "xyes"]) + + AS_IF([test "x${ac_cv_libwolfssl}" = "xyes"],[ + save_LIBS="${LIBS}" + LIBS="${LIBS} ${LTLIBWOLFSSL}" + AC_CHECK_FUNCS(wolfSSL_Cleanup) + LIBS="$save_LIBS" + ]) +]) + +AC_DEFUN([_TAO_HAVE_LIBWOLFSSL],[ + + AC_ARG_ENABLE([libwolfssl], + [AS_HELP_STRING([--disable-libwolfssl], + [Build with libwolfssl support @<:@default=on@:>@])], + [ac_enable_libwolfssl="$enableval"], + [ac_enable_libwolfssl="yes"]) + + _TAO_SEARCH_LIBWOLFSSL +]) + + +AC_DEFUN([TAO_HAVE_LIBWOLFSSL],[ + AC_REQUIRE([_TAO_HAVE_LIBWOLFSSL]) +]) + +AC_DEFUN([_TAO_REQUIRE_LIBWOLFSSL],[ + ac_enable_libwolfssl="yes" + _TAO_SEARCH_LIBWOLFSSL + + AS_IF([test x$ac_cv_libwolfssl = xno],[ + AC_MSG_ERROR([libwolfssl is required for ${PACKAGE}, It can be obtained from http://www.wolfssl.com/download.html/]) + ]) +]) + +AC_DEFUN([TAO_REQUIRE_LIBWOLFSSL],[ + AC_REQUIRE([_TAO_REQUIRE_LIBWOLFSSL]) +]) diff --git a/m4/hexversion.m4 b/m4/hexversion.m4 new file mode 100644 index 0000000..8d26155 --- /dev/null +++ b/m4/hexversion.m4 @@ -0,0 +1,6 @@ +AC_DEFUN([CREATE_HEX_VERSION],[ + + HEX_VERSION=`echo $VERSION | sed 's|[\-a-z0-9]*$||' | \ + awk -F. '{printf "0x%0.2d%0.3d%0.3d", $[]1, $[]2, $[]3}'` + AC_SUBST([HEX_VERSION]) +]) diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4 new file mode 100644 index 0000000..96c4e2c --- /dev/null +++ b/m4/lib-ld.m4 @@ -0,0 +1,110 @@ +# lib-ld.m4 serial 3 (gettext-0.13) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/m4/lib-link.m4 b/m4/lib-link.m4 new file mode 100644 index 0000000..c30c38a --- /dev/null +++ b/m4/lib-link.m4 @@ -0,0 +1,767 @@ +# lib-link.m4 serial 18 (gettext-0.18) +dnl Copyright (C) 2001-2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ([2.54]) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + popdef([NAME]) + popdef([Name]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [system]) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2], [$5]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + LIB[]NAME[]_PREFIX= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + popdef([NAME]) + popdef([Name]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +dnl acl_hardcode_libdir_flag_spec, +dnl acl_hardcode_libdir_separator, +dnl acl_hardcode_direct, +dnl acl_hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies, system]) searches for +dnl libname and the libraries corresponding to explicit and implicit +dnl dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +dnl If system==system, -isystem is used instead of -I +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl Autoconf >= 2.61 supports dots in --with options. + pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + if test "x$GCC" = "xyes" -a "x$3" = "xsystem" + then + i_system="-isystem " + else + i_system="-I" + fi + + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(P_A_C_K[-prefix], +[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X${i_system}$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }${i_system}$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([P_A_C_K]) + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4 new file mode 100644 index 0000000..bab0cb7 --- /dev/null +++ b/m4/lib-prefix.m4 @@ -0,0 +1,221 @@ +# lib-prefix.m4 serial 6 (gettext-0.18) +dnl Copyright (C) 2001-2005, 2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl . + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM([], [[ + return sizeof(void*) == 8 ? 0 : 1; + ]]) + ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) + ]) + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" +]) diff --git a/m4/visibility.m4 b/m4/visibility.m4 new file mode 100644 index 0000000..75c34b6 --- /dev/null +++ b/m4/visibility.m4 @@ -0,0 +1,77 @@ +# visibility.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2005, 2008, 2010-2011 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +AC_DEFUN([gl_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + CFLAG_VISIBILITY= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + dnl First, check whether -Werror can be added to the command line, or + dnl whether it leads to an error because of some other option that the + dnl user has put into $CC $CFLAGS $CPPFLAGS. + AC_MSG_CHECKING([whether the -Werror option is usable]) + AC_CACHE_VAL([gl_cv_cc_vis_werror], [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [gl_cv_cc_vis_werror=yes], + [gl_cv_cc_vis_werror=no]) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_vis_werror]) + dnl Now check whether visibility declarations are supported. + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL([gl_cv_cc_visibility], [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + dnl We use the option -Werror and a function dummyfunc, because on some + dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning + dnl "visibility attribute not supported in this configuration; ignored" + dnl at the first function definition in every compilation unit, and we + dnl don't want to use the option in this case. + if test $gl_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void) {} + ]], + [[]])], + [gl_cv_cc_visibility=yes], + [gl_cv_cc_visibility=no]) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_visibility]) + if test $gl_cv_cc_visibility = yes; then + CFLAG_VISIBILITY="-fvisibility=hidden" + HAVE_VISIBILITY=1 + fi + fi + AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/m4/wolfssl_darwin_clang.m4 b/m4/wolfssl_darwin_clang.m4 new file mode 100644 index 0000000..fee9b6a --- /dev/null +++ b/m4/wolfssl_darwin_clang.m4 @@ -0,0 +1,37 @@ +# =========================================================================== +# +# SYNOPSIS +# +# WOLFSSL_DARWIN_USING_CLANG +# +# DESCRIPTION +# +# With the advent of Apple Xcode v5.0, the old tool sets are missing from +# the distribution. The provided "gcc" executable wrapper accepts the +# "-pthread" flag, and passes it to the underlying "clang" which chokes +# on it. This script checks the version of the gcc executable to see if +# it reports it is really "clang". +# +# The value is placed in the wolfssl_darwin_clang variable. +# +# LICENSE +# +# Copyright (c) 2013 John Safranek +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 1 + +AC_DEFUN([WOLFSSL_DARWIN_USING_CLANG], + [ + if test x"$CC" = xclang; then + wolfssl_darwin_clang=yes + elif test x"$CC" = x || test x"$CC" = xgcc; then + if /usr/bin/gcc -v 2>&1 | grep 'clang' >/dev/null 2>&1; then + wolfssl_darwin_clang=yes + fi + fi + ]) diff --git a/pre-commit.sh b/pre-commit.sh new file mode 100755 index 0000000..01f0653 --- /dev/null +++ b/pre-commit.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# +# Our "pre-commit" hook. + +# save current config +echo "\n\nSaving current config\n\n" +cp config.status tmp.status +cp wolftpm/options.h tmp.options.h + +# stash modified files not part of this commit, don't test them +echo "\n\nStashing any modified files not part of commit\n\n" +git stash -q --keep-index + +# do the commit tests +echo "\n\nRunning commit tests...\n\n" +./commit-tests.sh +RESULT=$? + +# restore modified files not part of this commit +echo "\n\nPopping any stashed modified files not part of commit\n" +git stash pop -q + +# restore current config +echo "\nRestoring current config\n" +mv tmp.status config.status +# don't show output incase error from above +./config.status >/dev/null 2>&1 +mv tmp.options.h wolftpm/options.h +make clean >/dev/null 2>&1 +make -j 8 >/dev/null 2>&1 + +[ $RESULT -ne 0 ] && echo "\nOops, your commit failed\n" && exit 1 + +echo "\nCommit tests passed!\n" +exit 0 diff --git a/src/include.am b/src/include.am new file mode 100644 index 0000000..aa0b823 --- /dev/null +++ b/src/include.am @@ -0,0 +1,12 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + + +lib_LTLIBRARIES+= src/libwolftpm.la +src_libwolftpm_la_SOURCES = src/tpm2.c +src_libwolftpm_la_CFLAGS = -DBUILDING_WOLFTPM $(AM_CFLAGS) +src_libwolftpm_la_CPPFLAGS = -DBUILDING_WOLFTPM $(AM_CPPFLAGS) +src_libwolftpm_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined -version-info ${WOLFMQTT_LIBRARY_VERSION} +src_libwolftpm_la_DEPENDENCIES = +EXTRA_DIST += diff --git a/src/tpm2.c b/src/tpm2.c new file mode 100644 index 0000000..2cf25ca --- /dev/null +++ b/src/tpm2.c @@ -0,0 +1,5081 @@ +/* tpm2.c + * + * Copyright (C) 2006-2017 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifndef WOLFSSL_USER_SETTINGS + #include +#else + #include +#endif + +#include +#include +#include +#include + + +static inline word32 rotlFixed(word32 x, word32 y) { + return (x << y) | (x >> (sizeof(y) * 8 - y)); +} +static inline word32 rotrFixed(word32 x, word32 y) { + return (x >> y) | (x << (sizeof(y) * 8 - y)); +} + +static inline word16 ByteReverseWord16(word16 value) +{ +#if defined(__ICCARM__) + return (word16)__REV16(value); +#elif defined(KEIL_INTRINSICS) + return (word16)__rev16(value); +#elif defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3) + return (word16)__builtin_bswap16(value); +#else + return (value >> 8) | (value << 8); +#endif +} + +static inline word32 ByteReverseWord32(word32 value) +{ +#ifdef PPC_INTRINSICS + /* PPC: load reverse indexed instruction */ + return (word32)__lwbrx(&value,0); +#elif defined(__ICCARM__) + return (word32)__REV(value); +#elif defined(KEIL_INTRINSICS) + return (word32)__rev(value); +#elif defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3) + return (word32)__builtin_bswap32(value); +#elif defined(FAST_ROTATE) + /* 5 instructions with rotate instruction, 9 without */ + return (rotrFixed(value, 8U) & 0xff00ff00) | + (rotlFixed(value, 8U) & 0x00ff00ff); +#else + /* 6 instructions with rotate instruction, 8 without */ + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return rotlFixed(value, 16U); +#endif +} + +static inline word64 ByteReverseWord64(word64 value) +{ + return (word64)((word64)ByteReverseWord32((word32) value)) << 32 | + (word64)ByteReverseWord32((word32)(value >> 32)); +} + + +#define cpu_to_be16 ByteReverseWord16 +#define cpu_to_be32 ByteReverseWord32 +#define cpu_to_be64 ByteReverseWord64 +#define be16_to_cpu ByteReverseWord16 +#define be32_to_cpu ByteReverseWord32 +#define be64_to_cpu ByteReverseWord64 + + +/* Local Variables */ +static TPM2_CTX* gActiveTPM; + + +/* Local Functions */ +static INLINE TPM2_CTX* TPM2_GetActiveCtx(void) +{ + return gActiveTPM; +} + +static TPM_RC TPM2_AcquireLock(TPM2_CTX* ctx) +{ +#ifdef SINGLE_THREADED + (void)ctx; +#else + int ret = wc_LockMutex(&ctx->hwLock); + if (ret != 0) + return TPM_RC_FAILURE; +#endif + return TPM_RC_SUCCESS; +} + +static void TPM2_ReleaseLock(TPM2_CTX* ctx) +{ +#ifdef SINGLE_THREADED + (void)ctx; +#else + wc_UnLockMutex(&ctx->hwLock); +#endif +} + + + +/******************************************************************************/ +/* --- BEGIN TPM Interface Specification (TIS) Layer */ +/******************************************************************************/ +typedef struct TPM2_HEADER { + UINT16 tag; + UINT32 size; + union { + UINT32 code; + TPM_CC cc; + TPM_RC rc; + }; +} WOLFSSL_PACK TPM2_HEADER; + +#define TPM_TIS_SPI_READ 0x80 +#define TPM_TIS_SPI_WRITE 0x00 + +enum tpm_tis_access { + TPM_ACCESS_VALID = 0x80, + TPM_ACCESS_ACTIVE_LOCALITY = 0x20, + TPM_ACCESS_REQUEST_PENDING = 0x04, + TPM_ACCESS_REQUEST_USE = 0x02, +}; + +enum tpm_tis_status { + TPM_STS_VALID = 0x80, + TPM_STS_COMMAND_READY = 0x40, + TPM_STS_GO = 0x20, + TPM_STS_DATA_AVAIL = 0x10, + TPM_STS_DATA_EXPECT = 0x08, + TPM_STS_SELF_TEST_DONE = 0x04, + TPM_STS_RESP_RETRY = 0x02, +}; + +enum tpm_tis_int_flags { + TPM_GLOBAL_INT_ENABLE = 0x80000000, + TPM_INTF_BURST_COUNT_STATIC = 0x100, + TPM_INTF_CMD_READY_INT = 0x080, + TPM_INTF_INT_EDGE_FALLING = 0x040, + TPM_INTF_INT_EDGE_RISING = 0x020, + TPM_INTF_INT_LEVEL_LOW = 0x010, + TPM_INTF_INT_LEVEL_HIGH = 0x008, + TPM_INTF_LOC_CHANGE_INT = 0x004, + TPM_INTF_STS_VALID_INT = 0x002, + TPM_INTF_DATA_AVAIL_INT = 0x001, +}; + +#define TPM_ACCESS(l) (0x0000 | ((l) << 12)) +#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12)) +#define TPM_INT_VECTOR(l) (0x000C | ((l) << 12)) +#define TPM_INT_STATUS(l) (0x0010 | ((l) << 12)) +#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12)) +#define TPM_STS(l) (0x0018 | ((l) << 12)) +#define TPM_STS3(l) (0x001b | ((l) << 12)) +#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12)) + +#define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) +#define TPM_RID(l) (0x0F04 | ((l) << 12)) + + +static int TPM2_TIS_SpiRead(TPM2_CTX* ctx, word32 addr, byte* result, + word32 len) +{ + int rc; + byte txBuf[MAX_SPI_FRAMESIZE+4]; + byte rxBuf[MAX_SPI_FRAMESIZE+4]; + + if (ctx == NULL || result == NULL || len == 0 || len > MAX_SPI_FRAMESIZE) + return BAD_FUNC_ARG; + + txBuf[0] = TPM_TIS_SPI_READ | ((len & 0xFF) - 1); + txBuf[1] = (addr>>16) & 0xFF; + txBuf[2] = (addr>>8) & 0xFF; + txBuf[3] = (addr) & 0xFF; + XMEMSET(&txBuf[4], 0, len); + + rc = ctx->ioCb(ctx, txBuf, rxBuf, len + 4, ctx->userCtx); + + XMEMCPY(result, &rxBuf[4], len); + + return rc; +} + +static int TPM2_TIS_SpiWrite(TPM2_CTX* ctx, word32 addr, const byte* value, + word32 len) +{ + int rc; + byte txBuf[MAX_SPI_FRAMESIZE+4]; + byte rxBuf[MAX_SPI_FRAMESIZE+4]; + + if (ctx == NULL || value == NULL || len == 0 || len > MAX_SPI_FRAMESIZE) + return BAD_FUNC_ARG; + + txBuf[0] = TPM_TIS_SPI_WRITE | ((len & 0xFF) - 1); + txBuf[1] = (addr>>16) & 0xFF; + txBuf[2] = (addr>>8) & 0xFF; + txBuf[3] = (addr) & 0xFF; + XMEMCPY(&txBuf[4], value, len); + + rc = ctx->ioCb(ctx, txBuf, rxBuf, len + 4, ctx->userCtx); + + return rc; +} + +static int TPM2_TIS_StartupWait(TPM2_CTX* ctx, int timeout) +{ + int rc; + byte access; + + do { + rc = TPM2_TIS_SpiRead(ctx, TPM_ACCESS(0), &access, sizeof(access)); + if (access & TPM_ACCESS_VALID) + return 0; + } while (rc == TPM_RC_SUCCESS && --timeout > 0); + return -1; +} + +static int TPM2_TIS_CheckLocality(TPM2_CTX* ctx, int locality) +{ + int rc; + byte access; + + rc = TPM2_TIS_SpiRead(ctx, TPM_ACCESS(locality), &access, sizeof(access)); + if (rc == TPM_RC_SUCCESS && + ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == + (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))) { + ctx->locality = locality; + return locality; + } + return -1; +} + +static int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout) +{ + int rc; + int locality = 0; + byte access; + + rc = TPM2_TIS_CheckLocality(ctx, locality); + if (rc >= 0) + return rc; + + access = TPM_ACCESS_REQUEST_USE; + rc = TPM2_TIS_SpiWrite(ctx, TPM_ACCESS(locality), &access, sizeof(access)); + if (rc == TPM_RC_SUCCESS) { + do { + rc = TPM2_TIS_CheckLocality(ctx, locality); + if (rc >= 0) + return rc; + } while (--timeout > 0); + } + + return -1; +} + +static int TPM2_TIS_GetInfo(TPM2_CTX* ctx) +{ + word32 reg; + int rc; + + rc = TPM2_TIS_SpiRead(ctx, TPM_INTF_CAPS(ctx->locality), (byte*)®, + sizeof(reg)); + if (rc == TPM_RC_SUCCESS) { + ctx->caps = reg; + } + + rc = TPM2_TIS_SpiRead(ctx, TPM_DID_VID(ctx->locality), (byte*)®, + sizeof(reg)); + if (rc == TPM_RC_SUCCESS) { + ctx->did_vid = reg; + } + + reg = 0; + rc = TPM2_TIS_SpiRead(ctx, TPM_RID(ctx->locality), (byte*)®, 1); + if (rc == TPM_RC_SUCCESS) { + ctx->rid = reg; + } + + printf("TPM2: Caps 0x%08x, Did 0x%04x, Vid 0x%04x, Rid 0x%2x \n", + ctx->caps, ctx->did_vid >> 16, ctx->did_vid & 0xFFFF, ctx->rid); + + return rc; +} + +static byte TPM2_TIS_Status(TPM2_CTX* ctx) +{ + byte status = 0; + TPM2_TIS_SpiRead(ctx, TPM_STS(ctx->locality), &status, sizeof(status)); + return status; +} + +static byte TPM2_TIS_WaitForStatus(TPM2_CTX* ctx, byte status, byte status_mask) +{ + byte reg; + int timeout = TPM_TIMEOUT_TRIES; + do { + reg = TPM2_TIS_Status(ctx); + } while (((reg & status) != status_mask) && --timeout > 0); + if (timeout <= 0) + return -1; + return 0; +} + +static int TPM2_TIS_Ready(TPM2_CTX* ctx) +{ + byte status = TPM_STS_COMMAND_READY; + TPM2_TIS_SpiWrite(ctx, TPM_STS(ctx->locality), &status, sizeof(status)); + return 0; +} + +static int TPM2_TIS_GetBurstCount(TPM2_CTX* ctx) +{ + int rc; + word16 burstCount; + + do { + rc = TPM2_TIS_SpiRead(ctx, TPM_STS(ctx->locality) + 1, + (byte*)&burstCount, sizeof(burstCount)); + if (rc != TPM_RC_SUCCESS) + return -1; + } while (burstCount == 0); + + if (burstCount > MAX_SPI_FRAMESIZE) + burstCount = MAX_SPI_FRAMESIZE; + + if (rc == TPM_RC_SUCCESS) + return burstCount; + + return 0; +} + +static int TPM2_TIS_SendCommand(TPM2_CTX* ctx, byte* cmd, word16 cmdSz) +{ + int rc; + int status, xferSz, pos, burstCount; + byte access; + word16 rspSz; + + /* Make sure TPM is ready for command */ + status = TPM2_TIS_Status(ctx); + if ((status & TPM_STS_COMMAND_READY) == 0) { + /* Tell TPM chip to expect a command */ + TPM2_TIS_Ready(ctx); + + /* Wait for command ready (TPM_STS_COMMAND_READY = 1) */ + rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_COMMAND_READY, + TPM_STS_COMMAND_READY); + } + + /* Write Command */ + pos = 0; + while (pos < cmdSz) { + burstCount = TPM2_TIS_GetBurstCount(ctx); + if (burstCount < 0) { + rc = burstCount; goto exit; + } + + xferSz = cmdSz - pos; + if (xferSz > burstCount) + xferSz = burstCount; + + rc = TPM2_TIS_SpiWrite(ctx, TPM_DATA_FIFO(ctx->locality), &cmd[pos], + xferSz); + if (rc != TPM_RC_SUCCESS) + goto exit; + pos += xferSz; + + if (pos < cmdSz) { + /* Wait for expect more data (TPM_STS_DATA_EXPECT = 1) */ + rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_EXPECT, + TPM_STS_DATA_EXPECT); + if (rc != 0) { + printf("TPM2_TIS_SendCommand write expected more data!\n"); + goto exit; + } + } + } + + /* Wait for TPM_STS_DATA_EXPECT = 0 and TPM_STS_VALID = 1 */ + rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_EXPECT | TPM_STS_VALID, + TPM_STS_VALID); + + /* Execute Command */ + access = TPM_STS_GO; + rc = TPM2_TIS_SpiWrite(ctx, TPM_STS(ctx->locality), &access, + sizeof(access)); + if (rc != TPM_RC_SUCCESS) + goto exit; + + /* Read response */ + pos = 0; + rspSz = sizeof(TPM2_HEADER); /* Read at least TPM header */ + while (pos < rspSz) { + /* Wait for data to be available (TPM_STS_DATA_AVAIL = 1) */ + rc = TPM2_TIS_WaitForStatus(ctx, TPM_STS_DATA_AVAIL, + TPM_STS_DATA_AVAIL); + if (rc != 0) { + printf("TPM2_TIS_SendCommand read no data available!\n"); + goto exit; + } + + burstCount = TPM2_TIS_GetBurstCount(ctx); + if (burstCount < 0) { + rc = burstCount; goto exit; + } + + xferSz = rspSz - pos; + if (xferSz > burstCount) + xferSz = burstCount; + + rc = TPM2_TIS_SpiRead(ctx, TPM_DATA_FIFO(ctx->locality), &cmd[pos], + xferSz); + if (rc != TPM_RC_SUCCESS) + goto exit; + + pos += xferSz; + + /* Get real response size */ + if (pos == (int)sizeof(TPM2_HEADER)) { + TPM2_HEADER* header = (TPM2_HEADER*)cmd; + rspSz = be32_to_cpu(header->size); + } + } + + rc = 0; + +exit: + /* Tell TPM we are done */ + TPM2_TIS_Ready(ctx); + + return rc; +} +/******************************************************************************/ +/* --- END TPM Interface Layer -- */ +/******************************************************************************/ + + + +/******************************************************************************/ +/* --- BEGIN TPM Packet Assembly / Parsing -- */ +/******************************************************************************/ + +typedef struct TPM2_Packet { + byte* buf; + int pos; + int size; +} TPM2_Packet; + +static void TPM2_Packet_Init(TPM2_CTX* ctx, TPM2_Packet* packet) { + if (ctx && packet) { + packet->buf = ctx->cmdBuf; + packet->pos = sizeof(TPM2_HEADER); /* skip header (fill during finalize) */ + packet->size = sizeof(ctx->cmdBuf); + } +} + +static void TPM2_Packet_AppendU8(TPM2_Packet* packet, UINT8 data) { + if (packet && (packet->pos + (int)sizeof(UINT8) <= packet->size)) { + packet->buf[packet->pos] = data; + packet->pos += sizeof(UINT8); + } +} +static void TPM2_Packet_AppendU16(TPM2_Packet* packet, UINT16 data) { + if (packet && (packet->pos + (int)sizeof(UINT16) <= packet->size)) { + data = cpu_to_be16(data); + XMEMCPY(&packet->buf[packet->pos], &data, sizeof(UINT16)); + packet->pos += sizeof(UINT16); + } +} +static void TPM2_Packet_AppendU32(TPM2_Packet* packet, UINT32 data) { + if (packet && (packet->pos + (int)sizeof(UINT32) <= packet->size)) { + data = cpu_to_be32(data); + XMEMCPY(&packet->buf[packet->pos], &data, sizeof(UINT32)); + packet->pos += sizeof(UINT32); + } +} +static void TPM2_Packet_AppendU64(TPM2_Packet* packet, UINT64 data) { + if (packet && (packet->pos + (int)sizeof(UINT64) <= packet->size)) { + data = cpu_to_be64(data); + XMEMCPY(&packet->buf[packet->pos], &data, sizeof(UINT64)); + packet->pos += sizeof(UINT64); + } +} +static void TPM2_Packet_AppendS32(TPM2_Packet* packet, INT32 data) { + if (packet && (packet->pos + (int)sizeof(INT32) <= packet->size)) { + data = cpu_to_be32(data); + XMEMCPY(&packet->buf[packet->pos], &data, sizeof(INT32)); + packet->pos += sizeof(INT32); + } +} +static void TPM2_Packet_AppendBytes(TPM2_Packet* packet, byte* buf, int size) { + if (packet && (packet->pos + size <= packet->size)) { + if (buf) + XMEMCPY(&packet->buf[packet->pos], buf, size); + packet->pos += size; + } +} +static void TPM2_Packet_AppendAuth(TPM2_Packet* packet, TPMS_AUTH_COMMAND* auth) +{ + word32 authCmdSz = sizeof(UINT32) + /* session handle */ + sizeof(UINT16) + auth->nonce.size + 1 + /* none and session attribute */ + sizeof(UINT16) + auth->hmac.size; /* hmac */ + TPM2_Packet_AppendU32(packet, authCmdSz); + TPM2_Packet_AppendU32(packet, auth->sessionHandle); + TPM2_Packet_AppendU16(packet, auth->nonce.size); + TPM2_Packet_AppendBytes(packet, auth->nonce.buffer, auth->nonce.size); + TPM2_Packet_AppendU8(packet, auth->sessionAttributes); + TPM2_Packet_AppendU16(packet, auth->hmac.size); + TPM2_Packet_AppendBytes(packet, auth->hmac.buffer, auth->hmac.size); +} +static void TPM2_Packet_AppendPCR(TPM2_Packet* packet, TPML_PCR_SELECTION* pcr) { + int i; + TPM2_Packet_AppendU32(packet, pcr->count); + for (i=0; i<(int)pcr->count; i++) { + TPM2_Packet_AppendU16(packet, pcr->pcrSelections[i].hash); + TPM2_Packet_AppendU8(packet, pcr->pcrSelections[i].sizeofSelect); + TPM2_Packet_AppendBytes(packet, + pcr->pcrSelections[i].pcrSelect, + pcr->pcrSelections[i].sizeofSelect); + } +} +static void TPM2_Packet_AppendPublic(TPM2_Packet* packet, TPM2B_PUBLIC* public) { + TPM2_Packet_AppendU16(packet, public->size); + TPM2_Packet_AppendU16(packet, public->publicArea.type); + TPM2_Packet_AppendU16(packet, public->publicArea.nameAlg); + TPM2_Packet_AppendU32(packet, public->publicArea.objectAttributes); + TPM2_Packet_AppendU16(packet, public->publicArea.authPolicy.size); + TPM2_Packet_AppendBytes(packet, public->publicArea.authPolicy.buffer, + public->publicArea.authPolicy.size); + switch (public->publicArea.type) { + case TPM_ALG_KEYEDHASH: + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.keyedHashDetail.scheme.scheme); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg); + + TPM2_Packet_AppendU16(packet, public->publicArea.unique.keyedHash.size); + TPM2_Packet_AppendBytes(packet, public->publicArea.unique.keyedHash.buffer, public->publicArea.unique.keyedHash.size); + break; + case TPM_ALG_SYMCIPHER: + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.symDetail.sym.algorithm); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.symDetail.sym.keyBits.sym); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.symDetail.sym.mode.sym); + break; + case TPM_ALG_RSA: + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.rsaDetail.symmetric.algorithm); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.rsaDetail.symmetric.keyBits.sym); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.rsaDetail.symmetric.mode.sym); + + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.rsaDetail.scheme.scheme); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.rsaDetail.scheme.details.anySig.hashAlg); + + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.rsaDetail.keyBits); + + TPM2_Packet_AppendU32(packet, public->publicArea.parameters.rsaDetail.exponent); + break; + case TPM_ALG_ECC: + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.symmetric.algorithm); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.symmetric.keyBits.sym); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.symmetric.mode.sym); + + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.scheme.scheme); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.scheme.details.any.hashAlg); + + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.curveID); + + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.kdf.scheme); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.eccDetail.kdf.details.any.hashAlg); + break; + default: + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.asymDetail.symmetric.algorithm); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.asymDetail.symmetric.keyBits.sym); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.asymDetail.symmetric.mode.sym); + + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.asymDetail.scheme.scheme); + TPM2_Packet_AppendU16(packet, public->publicArea.parameters.asymDetail.scheme.details.anySig.hashAlg); + break; + } +} +static void TPM2_Packet_AppendPoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point) { + TPM2_Packet_AppendU16(packet, point->size); + TPM2_Packet_AppendU16(packet, point->point.x.size); + TPM2_Packet_AppendBytes(packet, point->point.x.buffer, point->point.x.size); + TPM2_Packet_AppendU16(packet, point->point.y.size); + TPM2_Packet_AppendBytes(packet, point->point.y.buffer, point->point.y.size); +} + +static int TPM2_Packet_Finalize(TPM2_Packet* packet, TPM_ST tag, TPM_CC cc) { + word32 cmdSz = packet->pos; /* get total packet size */ + packet->pos = 0; /* reset position to front */ + TPM2_Packet_AppendU16(packet, tag); /* tag */ + TPM2_Packet_AppendU32(packet, cmdSz); /* command size */ + TPM2_Packet_AppendU32(packet, cc); /* command code */ + packet->pos = cmdSz; /* restore total size */ + return cmdSz; +} + +static void TPM2_Packet_ParseU8(TPM2_Packet* packet, UINT8* data) { + UINT8 value = 0; + if (packet && (packet->pos + (int)sizeof(UINT8) <= packet->size)) { + if (data) + value = packet->buf[packet->pos]; + packet->pos += sizeof(UINT8); + } + if (data) + *data = value; +} +static void TPM2_Packet_ParseU16(TPM2_Packet* packet, UINT16* data) { + UINT16 value = 0; + if (packet && (packet->pos + (int)sizeof(UINT16) <= packet->size)) { + XMEMCPY(&value, &packet->buf[packet->pos], sizeof(UINT16)); + value = be16_to_cpu(value); + packet->pos += sizeof(UINT16); + } + if (data) + *data = value; +} +static void TPM2_Packet_ParseU32(TPM2_Packet* packet, UINT32* data) { + UINT32 value = 0; + if (packet && (packet->pos + (int)sizeof(UINT32) <= packet->size)) { + if (data) { + XMEMCPY(&value, &packet->buf[packet->pos], sizeof(UINT32)); + value = be32_to_cpu(value); + } + packet->pos += sizeof(UINT32); + } + if (data) + *data = value; +} +static void TPM2_Packet_ParseU64(TPM2_Packet* packet, UINT64* data) { + UINT64 value = 0; + if (packet && (packet->pos + (int)sizeof(UINT64) <= packet->size)) { + if (data) { + XMEMCPY(&value, &packet->buf[packet->pos], sizeof(UINT64)); + value = be64_to_cpu(value); + } + packet->pos += sizeof(UINT64); + } + if (data) + *data = value; +} +static void TPM2_Packet_ParseBytes(TPM2_Packet* packet, byte* buf, int size) { + if (packet) { + if (buf) { + /* truncate result */ + int sizeToCopy = size; + if (packet->pos + sizeToCopy > packet->size) + sizeToCopy = packet->size - packet->pos; + XMEMCPY(buf, &packet->buf[packet->pos], sizeToCopy); + } + packet->pos += size; + } +} +static TPM_RC TPM2_Packet_Parse(TPM_RC rc, TPM2_Packet* packet) { + if (rc == TPM_RC_SUCCESS && packet) { + UINT32 tmpRc; + UINT32 respSz; + packet->pos = 0; /* reset position */ + TPM2_Packet_ParseU16(packet, NULL); /* tag */ + TPM2_Packet_ParseU32(packet, &respSz); /* response size */ + TPM2_Packet_ParseU32(packet, &tmpRc); /* response code */ + packet->size = respSz; + rc = tmpRc; + } + return rc; +} +static void TPM2_Packet_ParsePCR(TPM2_Packet* packet, TPML_PCR_SELECTION* pcr) { + int i; + TPM2_Packet_ParseU32(packet, &pcr->count); + for (i=0; i<(int)pcr->count; i++) { + TPM2_Packet_ParseU16(packet, &pcr->pcrSelections[i].hash); + TPM2_Packet_ParseU8(packet, &pcr->pcrSelections[i].sizeofSelect); + TPM2_Packet_ParseBytes(packet, + pcr->pcrSelections[i].pcrSelect, + pcr->pcrSelections[i].sizeofSelect); + } +} +static void TPM2_Packet_ParsePublic(TPM2_Packet* packet, TPM2B_PUBLIC* public) { + TPM2_Packet_ParseU16(packet, &public->size); + TPM2_Packet_ParseU16(packet, &public->publicArea.type); + TPM2_Packet_ParseU32(packet, &public->publicArea.objectAttributes); + TPM2_Packet_ParseU16(packet, &public->publicArea.authPolicy.size); + TPM2_Packet_ParseBytes(packet, + public->publicArea.authPolicy.buffer, + public->publicArea.authPolicy.size); + switch (public->publicArea.type) { + case TPM_ALG_KEYEDHASH: + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.keyedHashDetail.scheme.scheme); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.keyedHashDetail.scheme.details.hmac.hashAlg); + + TPM2_Packet_ParseU16(packet, &public->publicArea.unique.keyedHash.size); + TPM2_Packet_ParseBytes(packet, public->publicArea.unique.keyedHash.buffer, + public->publicArea.unique.keyedHash.size); + break; + case TPM_ALG_SYMCIPHER: + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.symDetail.sym.algorithm); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.symDetail.sym.keyBits.sym); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.symDetail.sym.mode.sym); + break; + case TPM_ALG_RSA: + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.rsaDetail.symmetric.algorithm); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.rsaDetail.symmetric.keyBits.sym); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.rsaDetail.symmetric.mode.sym); + + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.rsaDetail.scheme.scheme); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.rsaDetail.scheme.details.anySig.hashAlg); + + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.rsaDetail.keyBits); + + TPM2_Packet_ParseU32(packet, &public->publicArea.parameters.rsaDetail.exponent); + break; + case TPM_ALG_ECC: + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.symmetric.algorithm); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.symmetric.keyBits.sym); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.symmetric.mode.sym); + + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.scheme.scheme); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.scheme.details.any.hashAlg); + + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.curveID); + + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.kdf.scheme); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.eccDetail.kdf.details.any.hashAlg); + break; + default: + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.asymDetail.symmetric.algorithm); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.asymDetail.symmetric.keyBits.sym); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.asymDetail.symmetric.mode.sym); + + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.asymDetail.scheme.scheme); + TPM2_Packet_ParseU16(packet, &public->publicArea.parameters.asymDetail.scheme.details.anySig.hashAlg); + break; + } +} +static void TPM2_Packet_ParsePoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point) { + TPM2_Packet_ParseU16(packet, &point->size); + TPM2_Packet_ParseU16(packet, &point->point.x.size); + TPM2_Packet_ParseBytes(packet, point->point.x.buffer, point->point.x.size); + TPM2_Packet_ParseU16(packet, &point->point.y.size); + TPM2_Packet_ParseBytes(packet, point->point.y.buffer, point->point.y.size); +} + + +/******************************************************************************/ +/* --- END TPM Packet Assembly / Parsing -- */ +/******************************************************************************/ + + + +/* Send Command Wrapper */ +static TPM_RC TPM2_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet) +{ + if (ctx && packet) { + byte* cmd = packet->buf; + word16 cmdSz = packet->pos; + packet->pos = 0; /* reset size */ + return (TPM_RC)TPM2_TIS_SendCommand(ctx, cmd, cmdSz); + } + return TPM_RC_FAILURE; +} + +/* Standard TPM API's */ +TPM_RC TPM2_Init(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx) +{ + TPM_RC rc; + + if (ctx == NULL) { + return TPM_RC_FAILURE; + } + + XMEMSET(ctx, 0, sizeof(TPM2_CTX)); + ctx->ioCb = ioCb; + ctx->userCtx = userCtx; + +#ifndef SINGLE_THREADED + if (wc_InitMutex(&ctx->hwLock) != 0) { + WOLFSSL_MSG("TPM Mutex Init failed"); + return TPM_RC_FAILURE; + } +#endif + + /* Startup TIS */ + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + + /* Set the active TPM global */ + gActiveTPM = ctx; + + /* Wait for chip startup to complete */ + rc = TPM2_TIS_StartupWait(ctx, TPM_TIMEOUT_TRIES); + if (rc == TPM_RC_SUCCESS) { + + /* Request locality for TPM module */ + rc = TPM2_TIS_RequestLocality(ctx, TPM_TIMEOUT_TRIES); + if (rc == TPM_RC_SUCCESS) { + + /* Get device information */ + rc = TPM2_TIS_GetInfo(ctx); + } + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Startup(Startup_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU16(&packet, in->startupType); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Startup); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Shutdown(Shutdown_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU16(&packet, in->shutdownType); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Shutdown); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + +TPM_RC TPM2_SelfTest(SelfTest_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU8(&packet, in->fullTest); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_SelfTest); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_IncrementalSelfTest(IncrementalSelfTest_In* in, + IncrementalSelfTest_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + int i; + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->toTest.count); + for (i=0; i<(int)in->toTest.count; i++) { + TPM2_Packet_AppendU16(&packet, in->toTest.algorithms[i]); + } + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, + TPM_CC_IncrementalSelfTest); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + TPM2_Packet_ParseU32(&packet, &out->toDoList.count); + for (i=0; i<(int)out->toDoList.count; i++) { + TPM2_Packet_ParseU16(&packet, &out->toDoList.algorithms[i]); + } + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_GetTestResult(GetTestResult_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetTestResult); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + TPM2_Packet_ParseU16(&packet, &out->outData.size); + TPM2_Packet_ParseBytes(&packet, out->outData.buffer, + out->outData.size); + TPM2_Packet_ParseU16(&packet, &out->testResult); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_GetCapability(GetCapability_In* in, GetCapability_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + int i; + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->capability); + TPM2_Packet_AppendU32(&packet, in->property); + TPM2_Packet_AppendU32(&packet, in->propertyCount); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetCapability); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + TPM2_Packet_ParseU8(&packet, &out->moreData); + TPM2_Packet_ParseU32(&packet, &out->capabilityData.capability); + + switch (out->capabilityData.capability) { + case TPM_CAP_TPM_PROPERTIES: { + TPML_TAGGED_TPM_PROPERTY* prop = + &out->capabilityData.data.tpmProperties; + TPM2_Packet_ParseU32(&packet, &prop->count); + for (i=0; i<(int)prop->count; i++) { + TPM2_Packet_ParseU32(&packet, + &prop->tpmProperty[i].property); + TPM2_Packet_ParseU32(&packet, + &prop->tpmProperty[i].value); + } + break; + } + default: + printf("Unknown capability type 0x%x\n", + (unsigned int)out->capabilityData.capability); + rc = -1; + break; + } + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_GetRandom(GetRandom_In* in, GetRandom_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU16(&packet, in->bytesRequested); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetRandom); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + TPM2_Packet_ParseU16(&packet, &out->randomBytes.size); + TPM2_Packet_ParseBytes(&packet, out->randomBytes.buffer, + out->randomBytes.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_StirRandom(StirRandom_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU16(&packet, in->inData.size); + TPM2_Packet_AppendBytes(&packet, in->inData.buffer, in->inData.size); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_StirRandom); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + +TPM_RC TPM2_PCR_Read(PCR_Read_In* in, PCR_Read_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + int i; + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendPCR(&packet, &in->pcrSelectionIn); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PCR_Read); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->pcrUpdateCounter); + TPM2_Packet_ParsePCR(&packet, &out->pcrSelectionOut); + TPM2_Packet_ParseU32(&packet, &out->pcrValues.count); + for (i=0; i<(int)out->pcrValues.count; i++) { + TPM2_Packet_ParseU16(&packet, &out->pcrValues.digests[i].size); + TPM2_Packet_ParseBytes(&packet, + out->pcrValues.digests[i].buffer, + out->pcrValues.digests[i].size); + } + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PCR_Extend(PCR_Extend_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + int i; + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->pcrHandle); + TPM2_Packet_AppendAuth(&packet, &in->auth); + TPM2_Packet_AppendU32(&packet, in->digests.count); + for (i=0; i<(int)in->digests.count; i++) { + UINT16 hashAlg = in->digests.digests[i].hashAlg; + int digestSz = TPM2_GetHashDigestSize(hashAlg); + TPM2_Packet_AppendU16(&packet, hashAlg); + TPM2_Packet_AppendBytes(&packet, in->digests.digests[i].digest.H, + digestSz); + } + TPM2_Packet_Finalize(&packet, TPM_ST_SESSIONS, TPM_CC_PCR_Extend); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + +TPM_RC TPM2_Create(Create_In* in, Create_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->parentHandle); + TPM2_Packet_AppendAuth(&packet, &in->auth); + + TPM2_Packet_AppendU16(&packet, in->inSensitive.size); + TPM2_Packet_AppendU16(&packet, in->inSensitive.sensitive.userAuth.size); + TPM2_Packet_AppendBytes(&packet, in->inSensitive.sensitive.userAuth.buffer, + in->inSensitive.sensitive.userAuth.size); + TPM2_Packet_AppendU16(&packet, in->inSensitive.sensitive.data.size); + TPM2_Packet_AppendBytes(&packet, in->inSensitive.sensitive.data.buffer, + in->inSensitive.sensitive.data.size); + + TPM2_Packet_AppendPublic(&packet, &in->inPublic); + + TPM2_Packet_AppendU16(&packet, in->outsideInfo.size); + TPM2_Packet_AppendBytes(&packet, in->outsideInfo.buffer, in->outsideInfo.size); + + TPM2_Packet_AppendPCR(&packet, &in->creationPCR); + + TPM2_Packet_Finalize(&packet, TPM_ST_SESSIONS, TPM_CC_Create); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outPrivate.size); + TPM2_Packet_ParseBytes(&packet, out->outPrivate.buffer, out->outPrivate.size); + + TPM2_Packet_ParsePublic(&packet, &out->outPublic); + + TPM2_Packet_ParseU16(&packet, &out->creationData.size); + TPM2_Packet_ParsePCR(&packet, &out->creationData.creationData.pcrSelect); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.pcrDigest.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.pcrDigest.buffer, + out->creationData.creationData.pcrDigest.size); + TPM2_Packet_ParseU8(&packet, &out->creationData.creationData.locality); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.parentNameAlg); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.parentName.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.parentName.name, + out->creationData.creationData.parentName.size); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.parentQualifiedName.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.parentQualifiedName.name, + out->creationData.creationData.parentQualifiedName.size); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.outsideInfo.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.outsideInfo.buffer, + out->creationData.creationData.outsideInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->creationHash.size); + TPM2_Packet_ParseBytes(&packet, + out->creationHash.buffer, + out->creationHash.size); + + TPM2_Packet_ParseU16(&packet, &out->creationTicket.tag); + TPM2_Packet_ParseU32(&packet, &out->creationTicket.hierarchy); + TPM2_Packet_ParseU16(&packet, &out->creationTicket.digest.size); + TPM2_Packet_ParseBytes(&packet, + out->creationTicket.digest.buffer, + out->creationTicket.digest.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_CreatePrimary(CreatePrimary_In* in, CreatePrimary_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->primaryHandle); + + TPM2_Packet_AppendU16(&packet, in->inSensitive.size); + TPM2_Packet_AppendU16(&packet, in->inSensitive.sensitive.userAuth.size); + TPM2_Packet_AppendBytes(&packet, in->inSensitive.sensitive.userAuth.buffer, + in->inSensitive.sensitive.userAuth.size); + TPM2_Packet_AppendU16(&packet, in->inSensitive.sensitive.data.size); + TPM2_Packet_AppendBytes(&packet, in->inSensitive.sensitive.data.buffer, + in->inSensitive.sensitive.data.size); + + TPM2_Packet_AppendPublic(&packet, &in->inPublic); + + TPM2_Packet_AppendU16(&packet, in->outsideInfo.size); + TPM2_Packet_AppendBytes(&packet, in->outsideInfo.buffer, in->outsideInfo.size); + + TPM2_Packet_AppendPCR(&packet, &in->creationPCR); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_CreatePrimary); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->objectHandle); + + TPM2_Packet_ParsePublic(&packet, &out->outPublic); + + TPM2_Packet_ParseU16(&packet, &out->creationData.size); + TPM2_Packet_ParsePCR(&packet, &out->creationData.creationData.pcrSelect); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.pcrDigest.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.pcrDigest.buffer, + out->creationData.creationData.pcrDigest.size); + TPM2_Packet_ParseU8(&packet, &out->creationData.creationData.locality); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.parentNameAlg); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.parentName.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.parentName.name, + out->creationData.creationData.parentName.size); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.parentQualifiedName.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.parentQualifiedName.name, + out->creationData.creationData.parentQualifiedName.size); + TPM2_Packet_ParseU16(&packet, &out->creationData.creationData.outsideInfo.size); + TPM2_Packet_ParseBytes(&packet, + out->creationData.creationData.outsideInfo.buffer, + out->creationData.creationData.outsideInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->creationHash.size); + TPM2_Packet_ParseBytes(&packet, + out->creationHash.buffer, + out->creationHash.size); + + TPM2_Packet_ParseU16(&packet, &out->creationTicket.tag); + TPM2_Packet_ParseU32(&packet, &out->creationTicket.hierarchy); + TPM2_Packet_ParseU16(&packet, &out->creationTicket.digest.size); + TPM2_Packet_ParseBytes(&packet, + out->creationTicket.digest.buffer, + out->creationTicket.digest.size); + + TPM2_Packet_ParseU16(&packet, &out->name.size); + TPM2_Packet_ParseBytes(&packet, out->name.name, out->name.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + +TPM_RC TPM2_Load(Load_In* in, Load_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->parentHandle); + TPM2_Packet_AppendAuth(&packet, &in->auth); + + TPM2_Packet_AppendU16(&packet, in->inPrivate.size); + TPM2_Packet_AppendBytes(&packet, in->inPrivate.buffer, in->inPrivate.size); + + TPM2_Packet_AppendPublic(&packet, &in->inPublic); + + TPM2_Packet_Finalize(&packet, TPM_ST_SESSIONS, TPM_CC_Load); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->objectHandle); + TPM2_Packet_ParseU16(&packet, &out->name.size); + TPM2_Packet_ParseBytes(&packet, out->name.name, out->name.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_FlushContext(FlushContext_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->flushHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_FlushContext); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Unseal(Unseal_In* in, Unseal_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->itemHandle); + TPM2_Packet_AppendAuth(&packet, &in->auth); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Unseal); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outData.size); + TPM2_Packet_ParseBytes(&packet, out->outData.buffer, out->outData.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_StartAuthSession(StartAuthSession_In* in, StartAuthSession_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->tpmKey); + TPM2_Packet_AppendU32(&packet, in->bind); + TPM2_Packet_AppendU16(&packet, in->nonceCaller.size); + TPM2_Packet_AppendBytes(&packet, in->nonceCaller.buffer, in->nonceCaller.size); + + TPM2_Packet_AppendU16(&packet, in->encryptedSalt.size); + TPM2_Packet_AppendBytes(&packet, in->encryptedSalt.secret, in->encryptedSalt.size); + + TPM2_Packet_AppendU8(&packet, in->sessionType); + + TPM2_Packet_AppendU16(&packet, in->symmetric.algorithm); + TPM2_Packet_AppendU16(&packet, in->symmetric.keyBits.sym); + TPM2_Packet_AppendU16(&packet, in->symmetric.mode.sym); + + TPM2_Packet_AppendU16(&packet, in->authHash); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_StartAuthSession); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->sessionHandle); + TPM2_Packet_ParseU16(&packet, &out->nonceTPM.size); + TPM2_Packet_ParseBytes(&packet, out->nonceTPM.buffer, out->nonceTPM.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyRestart(PolicyRestart_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->sessionHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyRestart); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_LoadExternal(LoadExternal_In* in, LoadExternal_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU16(&packet, in->inPrivate.size); + TPM2_Packet_AppendU16(&packet, in->inPrivate.sensitiveArea.sensitiveType); + TPM2_Packet_AppendU16(&packet, in->inPrivate.sensitiveArea.authValue.size); + TPM2_Packet_AppendBytes(&packet, + in->inPrivate.sensitiveArea.authValue.buffer, + in->inPrivate.sensitiveArea.authValue.size); + TPM2_Packet_AppendU16(&packet, in->inPrivate.sensitiveArea.seedValue.size); + TPM2_Packet_AppendBytes(&packet, + in->inPrivate.sensitiveArea.seedValue.buffer, + in->inPrivate.sensitiveArea.seedValue.size); + + TPM2_Packet_AppendU16(&packet, in->inPrivate.sensitiveArea.sensitive.any.size); + TPM2_Packet_AppendBytes(&packet, + in->inPrivate.sensitiveArea.sensitive.any.buffer, + in->inPrivate.sensitiveArea.sensitive.any.size); + + TPM2_Packet_AppendPublic(&packet, &in->inPublic); + TPM2_Packet_AppendU32(&packet, in->hierarchy); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_LoadExternal); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->objectHandle); + TPM2_Packet_ParseU16(&packet, &out->name.size); + TPM2_Packet_ParseBytes(&packet, out->name.name, out->name.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ReadPublic(ReadPublic_In* in, ReadPublic_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->objectHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ReadPublic); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParsePublic(&packet, &out->outPublic); + + TPM2_Packet_ParseU16(&packet, &out->name.size); + TPM2_Packet_ParseBytes(&packet, out->name.name, out->name.size); + + TPM2_Packet_ParseU16(&packet, &out->qualifiedName.size); + TPM2_Packet_ParseBytes(&packet, out->qualifiedName.name, out->qualifiedName.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ActivateCredential(ActivateCredential_In* in, + ActivateCredential_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->activateHandle); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_AppendU16(&packet, in->credentialBlob.size); + TPM2_Packet_AppendBytes(&packet, in->credentialBlob.buffer, in->credentialBlob.size); + + TPM2_Packet_AppendU16(&packet, in->secret.size); + TPM2_Packet_AppendBytes(&packet, in->secret.secret, in->secret.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ActivateCredential); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->certInfo.size); + TPM2_Packet_ParseBytes(&packet, out->certInfo.buffer, out->certInfo.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_MakeCredential(MakeCredential_In* in, MakeCredential_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->handle); + + TPM2_Packet_AppendU16(&packet, in->credential.size); + TPM2_Packet_AppendBytes(&packet, in->credential.buffer, in->credential.size); + + TPM2_Packet_AppendU16(&packet, in->objectName.size); + TPM2_Packet_AppendBytes(&packet, in->objectName.name, in->objectName.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_MakeCredential); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->credentialBlob.size); + TPM2_Packet_ParseBytes(&packet, out->credentialBlob.buffer, out->credentialBlob.size); + + TPM2_Packet_ParseU16(&packet, &out->secret.size); + TPM2_Packet_ParseBytes(&packet, out->secret.secret, out->secret.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ObjectChangeAuth(ObjectChangeAuth_In* in, ObjectChangeAuth_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->objectHandle); + TPM2_Packet_AppendU32(&packet, in->parentHandle); + + TPM2_Packet_AppendU16(&packet, in->newAuth.size); + TPM2_Packet_AppendBytes(&packet, in->newAuth.buffer, in->newAuth.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ObjectChangeAuth); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outPrivate.size); + TPM2_Packet_ParseBytes(&packet, out->outPrivate.buffer, out->outPrivate.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Duplicate(Duplicate_In* in, Duplicate_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->objectHandle); + TPM2_Packet_AppendU32(&packet, in->newParentHandle); + + TPM2_Packet_AppendU16(&packet, in->encryptionKeyIn.size); + TPM2_Packet_AppendBytes(&packet, in->encryptionKeyIn.buffer, in->encryptionKeyIn.size); + + TPM2_Packet_AppendU16(&packet, in->symmetricAlg.algorithm); + TPM2_Packet_AppendU16(&packet, in->symmetricAlg.keyBits.sym); + TPM2_Packet_AppendU16(&packet, in->symmetricAlg.mode.sym); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Duplicate); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->encryptionKeyOut.size); + TPM2_Packet_ParseBytes(&packet, out->encryptionKeyOut.buffer, out->encryptionKeyOut.size); + + TPM2_Packet_ParseU16(&packet, &out->duplicate.size); + TPM2_Packet_ParseBytes(&packet, out->duplicate.buffer, out->duplicate.size); + + TPM2_Packet_ParseU16(&packet, &out->outSymSeed.size); + TPM2_Packet_ParseBytes(&packet, out->outSymSeed.secret, out->outSymSeed.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Rewrap(Rewrap_In* in, Rewrap_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->oldParent); + TPM2_Packet_AppendU32(&packet, in->newParent); + + TPM2_Packet_AppendU16(&packet, in->inDuplicate.size); + TPM2_Packet_AppendBytes(&packet, in->inDuplicate.buffer, in->inDuplicate.size); + + TPM2_Packet_AppendU16(&packet, in->name.size); + TPM2_Packet_AppendBytes(&packet, in->name.name, in->name.size); + + TPM2_Packet_AppendU16(&packet, in->inSymSeed.size); + TPM2_Packet_AppendBytes(&packet, in->inSymSeed.secret, in->inSymSeed.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Rewrap); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outDuplicate.size); + TPM2_Packet_ParseBytes(&packet, out->outDuplicate.buffer, out->outDuplicate.size); + + TPM2_Packet_ParseU16(&packet, &out->outSymSeed.size); + TPM2_Packet_ParseBytes(&packet, out->outSymSeed.secret, out->outSymSeed.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Import(Import_In* in, Import_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->parentHandle); + + TPM2_Packet_AppendU16(&packet, in->encryptionKey.size); + TPM2_Packet_AppendBytes(&packet, in->encryptionKey.buffer, in->encryptionKey.size); + + TPM2_Packet_AppendPublic(&packet, &in->objectPublic); + + TPM2_Packet_AppendU16(&packet, in->duplicate.size); + TPM2_Packet_AppendBytes(&packet, in->duplicate.buffer, in->duplicate.size); + + TPM2_Packet_AppendU16(&packet, in->inSymSeed.size); + TPM2_Packet_AppendBytes(&packet, in->inSymSeed.secret, in->inSymSeed.size); + + TPM2_Packet_AppendU16(&packet, in->symmetricAlg.algorithm); + TPM2_Packet_AppendU16(&packet, in->symmetricAlg.keyBits.sym); + TPM2_Packet_AppendU16(&packet, in->symmetricAlg.mode.sym); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Import); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outPrivate.size); + TPM2_Packet_ParseBytes(&packet, out->outPrivate.buffer, out->outPrivate.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_RSA_Encrypt(RSA_Encrypt_In* in, RSA_Encrypt_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_AppendU16(&packet, in->message.size); + TPM2_Packet_AppendBytes(&packet, in->message.buffer, in->message.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.anySig.hashAlg); + + TPM2_Packet_AppendU16(&packet, in->label.size); + TPM2_Packet_AppendBytes(&packet, in->label.buffer, in->label.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_RSA_Encrypt); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outData.size); + TPM2_Packet_ParseBytes(&packet, out->outData.buffer, out->outData.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_RSA_Decrypt(RSA_Decrypt_In* in, RSA_Decrypt_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_AppendU16(&packet, in->cipherText.size); + TPM2_Packet_AppendBytes(&packet, in->cipherText.buffer, in->cipherText.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.anySig.hashAlg); + + TPM2_Packet_AppendU16(&packet, in->label.size); + TPM2_Packet_AppendBytes(&packet, in->label.buffer, in->label.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_RSA_Decrypt); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->message.size); + TPM2_Packet_ParseBytes(&packet, out->message.buffer, out->message.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ECDH_KeyGen(ECDH_KeyGen_In* in, ECDH_KeyGen_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ECDH_KeyGen); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParsePoint(&packet, &out->zPoint); + TPM2_Packet_ParsePoint(&packet, &out->pubPoint); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ECDH_ZGen(ECDH_ZGen_In* in, ECDH_ZGen_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + TPM2_Packet_AppendPoint(&packet, &in->inPoint); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ECDH_ZGen); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParsePoint(&packet, &out->outPoint); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ECC_Parameters(ECC_Parameters_In* in, + ECC_Parameters_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU16(&packet, in->curveID); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ECC_Parameters); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->parameters.curveID); + TPM2_Packet_ParseU16(&packet, &out->parameters.keySize); + TPM2_Packet_ParseU16(&packet, &out->parameters.kdf.scheme); + TPM2_Packet_ParseU16(&packet, &out->parameters.kdf.details.any.hashAlg); + + TPM2_Packet_ParseU16(&packet, &out->parameters.sign.scheme); + TPM2_Packet_ParseU16(&packet, &out->parameters.sign.details.any.hashAlg); + + TPM2_Packet_ParseU16(&packet, &out->parameters.p.size); + TPM2_Packet_ParseBytes(&packet, out->parameters.p.buffer, out->parameters.p.size); + + TPM2_Packet_ParseU16(&packet, &out->parameters.a.size); + TPM2_Packet_ParseBytes(&packet, out->parameters.a.buffer, out->parameters.a.size); + + TPM2_Packet_ParseU16(&packet, &out->parameters.b.size); + TPM2_Packet_ParseBytes(&packet, out->parameters.b.buffer, out->parameters.b.size); + + TPM2_Packet_ParseU16(&packet, &out->parameters.gX.size); + TPM2_Packet_ParseBytes(&packet, out->parameters.gX.buffer, out->parameters.gX.size); + + TPM2_Packet_ParseU16(&packet, &out->parameters.gY.size); + TPM2_Packet_ParseBytes(&packet, out->parameters.gY.buffer, out->parameters.gY.size); + + TPM2_Packet_ParseU16(&packet, &out->parameters.n.size); + TPM2_Packet_ParseBytes(&packet, out->parameters.n.buffer, out->parameters.n.size); + + TPM2_Packet_ParseU16(&packet, &out->parameters.h.size); + TPM2_Packet_ParseBytes(&packet, out->parameters.h.buffer, out->parameters.h.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ZGen_2Phase(ZGen_2Phase_In* in, ZGen_2Phase_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->keyA); + TPM2_Packet_AppendPoint(&packet, &in->inQsB); + TPM2_Packet_AppendPoint(&packet, &in->inQeB); + TPM2_Packet_AppendU16(&packet, in->inScheme); + TPM2_Packet_AppendU16(&packet, in->counter); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ZGen_2Phase); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParsePoint(&packet, &out->outZ1); + TPM2_Packet_ParsePoint(&packet, &out->outZ2); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_EncryptDecrypt(EncryptDecrypt_In* in, EncryptDecrypt_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + TPM2_Packet_AppendU8(&packet, in->decrypt); + TPM2_Packet_AppendU16(&packet, in->mode); + + TPM2_Packet_AppendU16(&packet, in->ivIn.size); + TPM2_Packet_AppendBytes(&packet, in->ivIn.buffer, in->ivIn.size); + + TPM2_Packet_AppendU16(&packet, in->inData.size); + TPM2_Packet_AppendBytes(&packet, in->inData.buffer, in->inData.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_EncryptDecrypt); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outData.size); + TPM2_Packet_ParseBytes(&packet, out->outData.buffer, out->outData.size); + + TPM2_Packet_ParseU16(&packet, &out->ivOut.size); + TPM2_Packet_ParseBytes(&packet, out->ivOut.buffer, out->ivOut.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_EncryptDecrypt2(EncryptDecrypt2_In* in, EncryptDecrypt2_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_AppendU16(&packet, in->inData.size); + TPM2_Packet_AppendBytes(&packet, in->inData.buffer, in->inData.size); + + TPM2_Packet_AppendU8(&packet, in->decrypt); + TPM2_Packet_AppendU16(&packet, in->mode); + + TPM2_Packet_AppendU16(&packet, in->ivIn.size); + TPM2_Packet_AppendBytes(&packet, in->ivIn.buffer, in->ivIn.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_EncryptDecrypt2); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outData.size); + TPM2_Packet_ParseBytes(&packet, out->outData.buffer, out->outData.size); + + TPM2_Packet_ParseU16(&packet, &out->ivOut.size); + TPM2_Packet_ParseBytes(&packet, out->ivOut.buffer, out->ivOut.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Hash(Hash_In* in, Hash_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU16(&packet, in->data.size); + TPM2_Packet_AppendBytes(&packet, in->data.buffer, in->data.size); + + TPM2_Packet_AppendU16(&packet, in->hashAlg); + TPM2_Packet_AppendU32(&packet, in->hierarchy); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Hash); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outHash.size); + TPM2_Packet_ParseBytes(&packet, out->outHash.buffer, out->outHash.size); + + TPM2_Packet_ParseU16(&packet, &out->validation.tag); + TPM2_Packet_ParseU32(&packet, &out->validation.hierarchy); + + TPM2_Packet_ParseU16(&packet, &out->validation.digest.size); + TPM2_Packet_ParseBytes(&packet, out->validation.digest.buffer, out->validation.digest.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_HMAC(HMAC_In* in, HMAC_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->handle); + + TPM2_Packet_AppendU16(&packet, in->buffer.size); + TPM2_Packet_AppendBytes(&packet, in->buffer.buffer, in->buffer.size); + + TPM2_Packet_AppendU16(&packet, in->hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_HMAC); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->outHMAC.size); + TPM2_Packet_ParseBytes(&packet, out->outHMAC.buffer, out->outHMAC.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_HMAC_Start(HMAC_Start_In* in, HMAC_Start_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->handle); + + TPM2_Packet_AppendU16(&packet, in->auth.size); + TPM2_Packet_AppendBytes(&packet, in->auth.buffer, in->auth.size); + + TPM2_Packet_AppendU16(&packet, in->hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_HMAC_Start); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->sequenceHandle); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_HashSequenceStart(HashSequenceStart_In* in, + HashSequenceStart_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU16(&packet, in->auth.size); + TPM2_Packet_AppendBytes(&packet, in->auth.buffer, in->auth.size); + + TPM2_Packet_AppendU16(&packet, in->hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_HashSequenceStart); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->sequenceHandle); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_SequenceUpdate(SequenceUpdate_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->sequenceHandle); + + TPM2_Packet_AppendU16(&packet, in->buffer.size); + TPM2_Packet_AppendBytes(&packet, in->buffer.buffer, in->buffer.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_SequenceUpdate); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_SequenceComplete(SequenceComplete_In* in, SequenceComplete_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->sequenceHandle); + + TPM2_Packet_AppendU16(&packet, in->buffer.size); + TPM2_Packet_AppendBytes(&packet, in->buffer.buffer, in->buffer.size); + + TPM2_Packet_AppendU32(&packet, in->hierarchy); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_SequenceComplete); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->result.size); + TPM2_Packet_ParseBytes(&packet, out->result.buffer, out->result.size); + + TPM2_Packet_ParseU16(&packet, &out->validation.tag); + TPM2_Packet_ParseU32(&packet, &out->validation.hierarchy); + + TPM2_Packet_ParseU16(&packet, &out->validation.digest.size); + TPM2_Packet_ParseBytes(&packet, out->validation.digest.buffer, out->validation.digest.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_EventSequenceComplete(EventSequenceComplete_In* in, + EventSequenceComplete_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->pcrHandle); + TPM2_Packet_AppendU32(&packet, in->sequenceHandle); + + TPM2_Packet_AppendU16(&packet, in->buffer.size); + TPM2_Packet_AppendBytes(&packet, in->buffer.buffer, in->buffer.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_EventSequenceComplete); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + int i, digestSz; + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->results.count); + for (i=0; i<(int)out->results.count; i++) { + TPM2_Packet_ParseU16(&packet, &out->results.digests[i].hashAlg); + digestSz = TPM2_GetHashDigestSize(out->results.digests[i].hashAlg); + TPM2_Packet_ParseBytes(&packet, out->results.digests[i].digest.H, digestSz); + } + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Certify(Certify_In* in, Certify_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->objectHandle); + TPM2_Packet_AppendU32(&packet, in->signHandle); + + TPM2_Packet_AppendU16(&packet, in->qualifyingData.size); + TPM2_Packet_AppendBytes(&packet, in->qualifyingData.buffer, in->qualifyingData.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Certify); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->certifyInfo.size); + TPM2_Packet_ParseBytes(&packet, out->certifyInfo.attestationData, out->certifyInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_CertifyCreation(CertifyCreation_In* in, CertifyCreation_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->signHandle); + TPM2_Packet_AppendU32(&packet, in->objectHandle); + + TPM2_Packet_AppendU16(&packet, in->qualifyingData.size); + TPM2_Packet_AppendBytes(&packet, in->qualifyingData.buffer, in->qualifyingData.size); + + TPM2_Packet_AppendU16(&packet, in->creationHash.size); + TPM2_Packet_AppendBytes(&packet, in->creationHash.buffer, in->creationHash.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_AppendU16(&packet, in->creationTicket.tag); + TPM2_Packet_AppendU32(&packet, in->creationTicket.hierarchy); + TPM2_Packet_AppendU16(&packet, in->creationTicket.digest.size); + TPM2_Packet_AppendBytes(&packet, + in->creationTicket.digest.buffer, + in->creationTicket.digest.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_CertifyCreation); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->certifyInfo.size); + TPM2_Packet_ParseBytes(&packet, out->certifyInfo.attestationData, out->certifyInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Quote(Quote_In* in, Quote_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->signHandle); + + TPM2_Packet_AppendU16(&packet, in->qualifyingData.size); + TPM2_Packet_AppendBytes(&packet, in->qualifyingData.buffer, in->qualifyingData.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_AppendPCR(&packet, &in->PCRselect); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Quote); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->quoted.size); + TPM2_Packet_ParseBytes(&packet, out->quoted.attestationData, out->quoted.size); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_GetSessionAuditDigest(GetSessionAuditDigest_In* in, + GetSessionAuditDigest_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->privacyAdminHandle); + TPM2_Packet_AppendU32(&packet, in->signHandle); + TPM2_Packet_AppendU32(&packet, in->sessionHandle); + + TPM2_Packet_AppendU16(&packet, in->qualifyingData.size); + TPM2_Packet_AppendBytes(&packet, in->qualifyingData.buffer, in->qualifyingData.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetSessionAuditDigest); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->auditInfo.size); + TPM2_Packet_ParseBytes(&packet, out->auditInfo.attestationData, out->auditInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_GetCommandAuditDigest(GetCommandAuditDigest_In* in, + GetCommandAuditDigest_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->privacyHandle); + TPM2_Packet_AppendU32(&packet, in->signHandle); + + TPM2_Packet_AppendU16(&packet, in->qualifyingData.size); + TPM2_Packet_AppendBytes(&packet, in->qualifyingData.buffer, in->qualifyingData.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetCommandAuditDigest); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->auditInfo.size); + TPM2_Packet_ParseBytes(&packet, out->auditInfo.attestationData, out->auditInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_GetTime(GetTime_In* in, GetTime_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->privacyAdminHandle); + TPM2_Packet_AppendU32(&packet, in->signHandle); + + TPM2_Packet_AppendU16(&packet, in->qualifyingData.size); + TPM2_Packet_AppendBytes(&packet, in->qualifyingData.buffer, in->qualifyingData.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetTime); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->timeInfo.size); + TPM2_Packet_ParseBytes(&packet, out->timeInfo.attestationData, out->timeInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Commit(Commit_In* in, Commit_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->signHandle); + TPM2_Packet_AppendPoint(&packet, &in->P1); + + TPM2_Packet_AppendU16(&packet, in->s2.size); + TPM2_Packet_AppendBytes(&packet, in->s2.buffer, in->s2.size); + + TPM2_Packet_AppendU16(&packet, in->y2.size); + TPM2_Packet_AppendBytes(&packet, in->y2.buffer, in->y2.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Commit); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParsePoint(&packet, &out->K); + TPM2_Packet_ParsePoint(&packet, &out->L); + TPM2_Packet_ParsePoint(&packet, &out->E); + TPM2_Packet_ParseU16(&packet, &out->counter); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_EC_Ephemeral(EC_Ephemeral_In* in, EC_Ephemeral_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->curveID); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_EC_Ephemeral); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParsePoint(&packet, &out->Q); + TPM2_Packet_ParseU16(&packet, &out->counter); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_VerifySignature(VerifySignature_In* in, + VerifySignature_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_AppendU16(&packet, in->digest.size); + TPM2_Packet_AppendBytes(&packet, in->digest.buffer, in->digest.size); + + TPM2_Packet_AppendU16(&packet, in->signature.sigAlgo); + TPM2_Packet_AppendU16(&packet, in->signature.signature.any.hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_VerifySignature); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->validation.tag); + TPM2_Packet_ParseU32(&packet, &out->validation.hierarchy); + TPM2_Packet_ParseU16(&packet, &out->validation.digest.size); + TPM2_Packet_ParseBytes(&packet, + out->validation.digest.buffer, + out->validation.digest.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Sign(Sign_In* in, Sign_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_AppendU16(&packet, in->digest.size); + TPM2_Packet_AppendBytes(&packet, in->digest.buffer, in->digest.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_AppendU16(&packet, in->validation.tag); + TPM2_Packet_AppendU32(&packet, in->validation.hierarchy); + + TPM2_Packet_AppendU16(&packet, in->validation.digest.size); + TPM2_Packet_AppendBytes(&packet, in->validation.digest.buffer, in->validation.digest.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Sign); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_SetCommandCodeAuditStatus( + SetCommandCodeAuditStatus_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + int i; + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->auth); + TPM2_Packet_AppendU16(&packet, in->auditAlg); + + TPM2_Packet_AppendU32(&packet, in->setList.count); + for (i=0; i<(int)in->setList.count; i++) { + TPM2_Packet_AppendU32(&packet, in->setList.commandCodes[i]); + } + + TPM2_Packet_AppendU32(&packet, in->clearList.count); + for (i=0; i<(int)in->clearList.count; i++) { + TPM2_Packet_AppendU32(&packet, in->clearList.commandCodes[i]); + } + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_SetCommandCodeAuditStatus); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PCR_Event(PCR_Event_In* in, PCR_Event_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->pcrHandle); + + TPM2_Packet_AppendU16(&packet, in->eventData.size); + TPM2_Packet_AppendBytes(&packet, in->eventData.buffer, in->eventData.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PCR_Event); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + int i; + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->digests.count); + for (i=0; (int)out->digests.count; i++) { + int digestSz; + TPM2_Packet_ParseU16(&packet, &out->digests.digests[i].hashAlg); + digestSz = TPM2_GetHashDigestSize(out->digests.digests[i].hashAlg); + TPM2_Packet_ParseBytes(&packet, out->digests.digests[i].digest.H, digestSz); + } + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PCR_Allocate(PCR_Allocate_In* in, PCR_Allocate_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendPCR(&packet, &in->pcrAllocation); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PCR_Allocate); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU8(&packet, &out->allocationSuccess); + TPM2_Packet_ParseU32(&packet, &out->maxPCR); + TPM2_Packet_ParseU32(&packet, &out->sizeNeeded); + TPM2_Packet_ParseU32(&packet, &out->sizeAvailable); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PCR_SetAuthPolicy(PCR_SetAuthPolicy_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + + TPM2_Packet_AppendU16(&packet, in->authPolicy.size); + TPM2_Packet_AppendBytes(&packet, in->authPolicy.buffer, in->authPolicy.size); + + TPM2_Packet_AppendU16(&packet, in->hashAlg); + TPM2_Packet_AppendU32(&packet, in->pcrNum); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PCR_SetAuthPolicy); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PCR_SetAuthValue(PCR_SetAuthValue_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->pcrHandle); + + TPM2_Packet_AppendU16(&packet, in->auth.size); + TPM2_Packet_AppendBytes(&packet, in->auth.buffer, in->auth.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PCR_SetAuthValue); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PCR_Reset(PCR_Reset_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->pcrHandle); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PCR_Reset); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicySigned(PolicySigned_In* in, PolicySigned_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authObject); + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->nonceTPM.size); + TPM2_Packet_AppendBytes(&packet, in->nonceTPM.buffer, in->nonceTPM.size); + + TPM2_Packet_AppendU16(&packet, in->cpHashA.size); + TPM2_Packet_AppendBytes(&packet, in->cpHashA.buffer, in->cpHashA.size); + + TPM2_Packet_AppendU16(&packet, in->policyRef.size); + TPM2_Packet_AppendBytes(&packet, in->policyRef.buffer, in->policyRef.size); + + TPM2_Packet_AppendS32(&packet, in->expiration); + + TPM2_Packet_AppendU16(&packet, in->auth.sigAlgo); + TPM2_Packet_AppendU16(&packet, in->auth.signature.any.hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicySigned); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->timeout.size); + TPM2_Packet_ParseBytes(&packet, out->timeout.buffer, out->timeout.size); + + TPM2_Packet_ParseU16(&packet, &out->policyTicket.tag); + TPM2_Packet_ParseU32(&packet, &out->policyTicket.hierarchy); + TPM2_Packet_ParseU16(&packet, &out->policyTicket.digest.size); + TPM2_Packet_ParseBytes(&packet, + out->policyTicket.digest.buffer, + out->policyTicket.digest.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicySecret(PolicySecret_In* in, PolicySecret_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->nonceTPM.size); + TPM2_Packet_AppendBytes(&packet, in->nonceTPM.buffer, in->nonceTPM.size); + + TPM2_Packet_AppendU16(&packet, in->cpHashA.size); + TPM2_Packet_AppendBytes(&packet, in->cpHashA.buffer, in->cpHashA.size); + + TPM2_Packet_AppendU16(&packet, in->policyRef.size); + TPM2_Packet_AppendBytes(&packet, in->policyRef.buffer, in->policyRef.size); + + TPM2_Packet_AppendS32(&packet, in->expiration); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicySecret); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->timeout.size); + TPM2_Packet_ParseBytes(&packet, out->timeout.buffer, out->timeout.size); + + TPM2_Packet_ParseU16(&packet, &out->policyTicket.tag); + TPM2_Packet_ParseU32(&packet, &out->policyTicket.hierarchy); + TPM2_Packet_ParseU16(&packet, &out->policyTicket.digest.size); + TPM2_Packet_ParseBytes(&packet, + out->policyTicket.digest.buffer, + out->policyTicket.digest.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyTicket(PolicyTicket_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->timeout.size); + TPM2_Packet_AppendBytes(&packet, in->timeout.buffer, in->timeout.size); + + TPM2_Packet_AppendU16(&packet, in->cpHashA.size); + TPM2_Packet_AppendBytes(&packet, in->cpHashA.buffer, in->cpHashA.size); + + TPM2_Packet_AppendU16(&packet, in->policyRef.size); + TPM2_Packet_AppendBytes(&packet, in->policyRef.buffer, in->policyRef.size); + + TPM2_Packet_AppendU16(&packet, in->authName.size); + TPM2_Packet_AppendBytes(&packet, in->authName.name, in->authName.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyTicket); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyOR(PolicyOR_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + int i; + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU32(&packet, in->pHashList.count); + for (i=0; i<(int)in->pHashList.count; i++) { + TPM2_Packet_AppendU16(&packet, in->pHashList.digests[i].size); + TPM2_Packet_AppendBytes(&packet, + in->pHashList.digests[i].buffer, + in->pHashList.digests[i].size); + } + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyOR); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyPCR(PolicyPCR_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->pcrDigest.size); + TPM2_Packet_AppendBytes(&packet, in->pcrDigest.buffer, in->pcrDigest.size); + + TPM2_Packet_AppendPCR(&packet, &in->pcrs); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyPCR); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyLocality(PolicyLocality_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + TPM2_Packet_AppendU8(&packet, in->locality); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyLocality); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyNV(PolicyNV_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->operandB.size); + TPM2_Packet_AppendBytes(&packet, in->operandB.buffer, in->operandB.size); + + TPM2_Packet_AppendU16(&packet, in->offset); + TPM2_Packet_AppendU16(&packet, in->operation); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyNV); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyCounterTimer(PolicyCounterTimer_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->operandB.size); + TPM2_Packet_AppendBytes(&packet, in->operandB.buffer, in->operandB.size); + + TPM2_Packet_AppendU16(&packet, in->offset); + TPM2_Packet_AppendU16(&packet, in->operation); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyCounterTimer); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyCommandCode(PolicyCommandCode_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU32(&packet, in->code); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyCommandCode); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyCpHash(PolicyCpHash_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->cpHashA.size); + TPM2_Packet_AppendBytes(&packet, in->cpHashA.buffer, in->cpHashA.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyCpHash); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyNameHash(PolicyNameHash_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->nameHash.size); + TPM2_Packet_AppendBytes(&packet, in->nameHash.buffer, in->nameHash.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyNameHash); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyDuplicationSelect(PolicyDuplicationSelect_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->objectName.size); + TPM2_Packet_AppendBytes(&packet, in->objectName.name, in->objectName.size); + + TPM2_Packet_AppendU16(&packet, in->newParentName.size); + TPM2_Packet_AppendBytes(&packet, in->newParentName.name, in->newParentName.size); + + TPM2_Packet_AppendU8(&packet, in->includeObject); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyDuplicationSelect); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyAuthorize(PolicyAuthorize_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->policySession); + + TPM2_Packet_AppendU16(&packet, in->approvedPolicy.size); + TPM2_Packet_AppendBytes(&packet, in->approvedPolicy.buffer, in->approvedPolicy.size); + + TPM2_Packet_AppendU16(&packet, in->policyRef.size); + TPM2_Packet_AppendBytes(&packet, in->policyRef.buffer, in->policyRef.size); + + TPM2_Packet_AppendU16(&packet, in->keySign.size); + TPM2_Packet_AppendBytes(&packet, in->keySign.name, in->keySign.size); + + TPM2_Packet_AppendU16(&packet, in->checkTicket.tag); + TPM2_Packet_AppendU32(&packet, in->checkTicket.hierarchy); + TPM2_Packet_AppendU16(&packet, in->checkTicket.digest.size); + TPM2_Packet_AppendBytes(&packet, + in->checkTicket.digest.buffer, + in->checkTicket.digest.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyAuthorize); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + +static TPM_RC TPM2_PolicySessionOnly(TPM_CC cc, TPMI_SH_POLICY policy) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, policy); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, cc); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + +TPM_RC TPM2_PolicyPhysicalPresence(PolicyPhysicalPresence_In* in) +{ + return TPM2_PolicySessionOnly(TPM_CC_PolicyPhysicalPresence, in->policySession); +} + +TPM_RC TPM2_PolicyAuthValue(PolicyAuthValue_In* in) +{ + return TPM2_PolicySessionOnly(TPM_CC_PolicyAuthValue, in->policySession); +} + +TPM_RC TPM2_PolicyPassword(PolicyPassword_In* in) +{ + return TPM2_PolicySessionOnly(TPM_CC_PolicyPassword, in->policySession); +} + +TPM_RC TPM2_PolicyGetDigest(PolicyGetDigest_In* in, PolicyGetDigest_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->policySession); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyGetDigest); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->policyDigest.size); + TPM2_Packet_ParseBytes(&packet, out->policyDigest.buffer, out->policyDigest.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyNvWritten(PolicyNvWritten_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->policySession); + TPM2_Packet_AppendU8(&packet, in->writtenSet); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyNvWritten); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyTemplate(PolicyTemplate_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->policySession); + TPM2_Packet_AppendU16(&packet, in->templateHash.size); + TPM2_Packet_AppendBytes(&packet, in->templateHash.buffer, in->templateHash.size); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyTemplate); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PolicyAuthorizeNV(PolicyAuthorizeNV_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + TPM2_Packet_AppendU32(&packet, in->policySession); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PolicyAuthorizeNV); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + +TPM_RC TPM2_HierarchyControl(HierarchyControl_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->enable); + TPM2_Packet_AppendU8(&packet, in->state); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_HierarchyControl); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_SetPrimaryPolicy(SetPrimaryPolicy_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU16(&packet, in->authPolicy.size); + TPM2_Packet_AppendBytes(&packet, in->authPolicy.buffer, in->authPolicy.size); + TPM2_Packet_AppendU16(&packet, in->hashAlg); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_SetPrimaryPolicy); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ChangePPS(ChangePPS_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ChangePPS); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ChangeEPS(ChangeEPS_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ChangeEPS); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_Clear(Clear_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_Clear); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ClearControl(ClearControl_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->auth); + TPM2_Packet_AppendU8(&packet, in->disable); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ClearControl); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_HierarchyChangeAuth(HierarchyChangeAuth_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU16(&packet, in->newAuth.size); + TPM2_Packet_AppendBytes(&packet, in->newAuth.buffer, in->newAuth.size); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_HierarchyChangeAuth); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_DictionaryAttackLockReset(DictionaryAttackLockReset_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->lockHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_DictionaryAttackLockReset); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_DictionaryAttackParameters(DictionaryAttackParameters_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->lockHandle); + TPM2_Packet_AppendU32(&packet, in->newMaxTries); + TPM2_Packet_AppendU32(&packet, in->newRecoveryTime); + TPM2_Packet_AppendU32(&packet, in->lockoutRecovery); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_DictionaryAttackParameters); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_PP_Commands(PP_Commands_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + int i; + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->auth); + + TPM2_Packet_AppendU32(&packet, in->setList.count); + for (i=0; i<(int)in->setList.count; i++) { + TPM2_Packet_AppendU32(&packet, in->setList.commandCodes[i]); + } + TPM2_Packet_AppendU32(&packet, in->clearList.count); + for (i=0; i<(int)in->clearList.count; i++) { + TPM2_Packet_AppendU32(&packet, in->clearList.commandCodes[i]); + } + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_PP_Commands); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_SetAlgorithmSet(SetAlgorithmSet_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->algorithmSet); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_SetAlgorithmSet); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_FieldUpgradeStart(FieldUpgradeStart_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authorization); + TPM2_Packet_AppendU32(&packet, in->keyHandle); + + TPM2_Packet_AppendU16(&packet, in->fuDigest.size); + TPM2_Packet_AppendBytes(&packet, in->fuDigest.buffer, in->fuDigest.size); + + TPM2_Packet_AppendU16(&packet, in->manifestSignature.sigAlgo); + TPM2_Packet_AppendU16(&packet, in->manifestSignature.signature.any.hashAlg); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_FieldUpgradeStart); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_FieldUpgradeData(FieldUpgradeData_In* in, FieldUpgradeData_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU16(&packet, in->fuData.size); + TPM2_Packet_AppendBytes(&packet, in->fuData.buffer, in->fuData.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_FieldUpgradeData); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + int digestSz; + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->nextDigest.hashAlg); + digestSz = TPM2_GetHashDigestSize(out->nextDigest.hashAlg); + TPM2_Packet_ParseBytes(&packet, out->nextDigest.digest.H, digestSz); + + TPM2_Packet_ParseU16(&packet, &out->firstDigest.hashAlg); + digestSz = TPM2_GetHashDigestSize(out->firstDigest.hashAlg); + TPM2_Packet_ParseBytes(&packet, out->firstDigest.digest.H, digestSz); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_FirmwareRead(FirmwareRead_In* in, FirmwareRead_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->sequenceNumber); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_FirmwareRead); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->fuData.size); + TPM2_Packet_ParseBytes(&packet, out->fuData.buffer, out->fuData.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ContextSave(ContextSave_In* in, ContextSave_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->saveHandle); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ContextSave); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU64(&packet, &out->context.sequence); + TPM2_Packet_ParseU32(&packet, &out->context.savedHandle); + TPM2_Packet_ParseU32(&packet, &out->context.hierarchy); + + TPM2_Packet_ParseU16(&packet, &out->context.contextBlob.size); + TPM2_Packet_ParseBytes(&packet, out->context.contextBlob.buffer, + out->context.contextBlob.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ContextLoad(ContextLoad_In* in, ContextLoad_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU64(&packet, in->context.sequence); + TPM2_Packet_AppendU32(&packet, in->context.savedHandle); + TPM2_Packet_AppendU32(&packet, in->context.hierarchy); + + TPM2_Packet_AppendU16(&packet, in->context.contextBlob.size); + TPM2_Packet_AppendBytes(&packet, in->context.contextBlob.buffer, + in->context.contextBlob.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ContextLoad); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU32(&packet, &out->loadedHandle); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_EvictControl(EvictControl_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->auth); + TPM2_Packet_AppendU32(&packet, in->objectHandle); + TPM2_Packet_AppendU32(&packet, in->persistentHandle); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_EvictControl); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ReadClock(ReadClock_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ReadClock); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU64(&packet, &out->currentTime.time); + TPM2_Packet_ParseU64(&packet, &out->currentTime.clockInfo.clock); + TPM2_Packet_ParseU32(&packet, &out->currentTime.clockInfo.resetCount); + TPM2_Packet_ParseU32(&packet, &out->currentTime.clockInfo.restartCount); + TPM2_Packet_ParseU8(&packet, &out->currentTime.clockInfo.safe); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ClockSet(ClockSet_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->auth); + TPM2_Packet_AppendU64(&packet, in->newTime); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ClockSet); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_ClockRateAdjust(ClockRateAdjust_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU32(&packet, in->auth); + TPM2_Packet_AppendU8(&packet, in->rateAdjust); + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_ClockRateAdjust); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_TestParms(TestParms_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + TPM2_Packet_AppendU16(&packet, in->parameters.type); + switch (in->parameters.type) { + case TPM_ALG_KEYEDHASH: + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.keyedHashDetail.scheme.scheme); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.keyedHashDetail.scheme.details.hmac.hashAlg); + break; + case TPM_ALG_SYMCIPHER: + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.symDetail.sym.algorithm); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.symDetail.sym.keyBits.sym); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.symDetail.sym.mode.sym); + break; + case TPM_ALG_RSA: + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.rsaDetail.symmetric.algorithm); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.rsaDetail.symmetric.keyBits.sym); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.rsaDetail.symmetric.mode.sym); + + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.rsaDetail.scheme.scheme); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.rsaDetail.scheme.details.anySig.hashAlg); + + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.rsaDetail.keyBits); + + TPM2_Packet_AppendU32(&packet, in->parameters.parameters.rsaDetail.exponent); + break; + case TPM_ALG_ECC: + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.symmetric.algorithm); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.symmetric.keyBits.sym); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.symmetric.mode.sym); + + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.scheme.scheme); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.scheme.details.any.hashAlg); + + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.curveID); + + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.kdf.scheme); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.eccDetail.kdf.details.any.hashAlg); + break; + default: + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.asymDetail.symmetric.algorithm); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.asymDetail.symmetric.keyBits.sym); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.asymDetail.symmetric.mode.sym); + + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.asymDetail.scheme.scheme); + TPM2_Packet_AppendU16(&packet, in->parameters.parameters.asymDetail.scheme.details.anySig.hashAlg); + break; + } + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_TestParms); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_DefineSpace(NV_DefineSpace_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU16(&packet, in->auth.size); + TPM2_Packet_AppendBytes(&packet, in->auth.buffer, in->auth.size); + + TPM2_Packet_AppendU16(&packet, in->publicInfo.size); + TPM2_Packet_AppendU32(&packet, in->publicInfo.nvPublic.nvIndex); + TPM2_Packet_AppendU16(&packet, in->publicInfo.nvPublic.nameAlg); + TPM2_Packet_AppendU32(&packet, in->publicInfo.nvPublic.attributes); + + TPM2_Packet_AppendU16(&packet, in->publicInfo.nvPublic.authPolicy.size); + TPM2_Packet_AppendBytes(&packet, in->publicInfo.nvPublic.authPolicy.buffer, + in->publicInfo.nvPublic.authPolicy.size); + + TPM2_Packet_AppendU16(&packet, in->publicInfo.nvPublic.dataSize); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_DefineSpace); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_UndefineSpace(NV_UndefineSpace_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_UndefineSpace); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_UndefineSpaceSpecial(NV_UndefineSpaceSpecial_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->nvIndex); + TPM2_Packet_AppendU32(&packet, in->platform); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_UndefineSpaceSpecial); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_ReadPublic(NV_ReadPublic_In* in, NV_ReadPublic_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_ReadPublic); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->nvPublic.size); + TPM2_Packet_ParseU32(&packet, &out->nvPublic.nvPublic.nvIndex); + TPM2_Packet_ParseU16(&packet, &out->nvPublic.nvPublic.nameAlg); + TPM2_Packet_ParseU32(&packet, &out->nvPublic.nvPublic.attributes); + + TPM2_Packet_ParseU16(&packet, &out->nvPublic.nvPublic.authPolicy.size); + TPM2_Packet_ParseBytes(&packet, out->nvPublic.nvPublic.authPolicy.buffer, + out->nvPublic.nvPublic.authPolicy.size); + + TPM2_Packet_ParseU16(&packet, &out->nvPublic.nvPublic.dataSize); + + TPM2_Packet_ParseU16(&packet, &out->nvName.size); + TPM2_Packet_ParseBytes(&packet, out->nvName.name, out->nvName.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_Write(NV_Write_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_AppendU16(&packet, in->data.size); + TPM2_Packet_AppendBytes(&packet, in->data.buffer, in->data.size); + + TPM2_Packet_AppendU16(&packet, in->offset); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_Write); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_Increment(NV_Increment_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_Increment); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_Extend(NV_Extend_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_AppendU16(&packet, in->data.size); + TPM2_Packet_AppendBytes(&packet, in->data.buffer, in->data.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_Extend); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_SetBits(NV_SetBits_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_AppendU64(&packet, in->bits); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_SetBits); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_WriteLock(NV_WriteLock_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_WriteLock); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_GlobalWriteLock(NV_GlobalWriteLock_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_GlobalWriteLock); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_Read(NV_Read_In* in, NV_Read_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_AppendU16(&packet, in->size); + TPM2_Packet_AppendU16(&packet, in->offset); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_Read); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->data.size); + TPM2_Packet_ParseBytes(&packet, out->data.buffer, out->data.size); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_ReadLock(NV_ReadLock_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_ReadLock); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_ChangeAuth(NV_ChangeAuth_In* in) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_AppendU16(&packet, in->newAuth.size); + TPM2_Packet_AppendBytes(&packet, in->newAuth.buffer, in->newAuth.size); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_ChangeAuth); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + +TPM_RC TPM2_NV_Certify(NV_Certify_In* in, NV_Certify_Out* out) +{ + TPM_RC rc; + TPM2_CTX* ctx = TPM2_GetActiveCtx(); + + if (ctx == NULL || in == NULL || out == NULL) + return TPM_RC_BAD_ARG; + + rc = TPM2_AcquireLock(ctx); + if (rc == TPM_RC_SUCCESS) { + TPM2_Packet packet; + TPM2_Packet_Init(ctx, &packet); + + TPM2_Packet_AppendU32(&packet, in->signHandle); + TPM2_Packet_AppendU32(&packet, in->authHandle); + TPM2_Packet_AppendU32(&packet, in->nvIndex); + + TPM2_Packet_AppendU16(&packet, in->qualifyingData.size); + TPM2_Packet_AppendBytes(&packet, in->qualifyingData.buffer, in->qualifyingData.size); + + TPM2_Packet_AppendU16(&packet, in->inScheme.scheme); + TPM2_Packet_AppendU16(&packet, in->inScheme.details.any.hashAlg); + + TPM2_Packet_AppendU16(&packet, in->size); + TPM2_Packet_AppendU16(&packet, in->offset); + + TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_NV_Certify); + + /* send command */ + rc = TPM2_SendCommand(ctx, &packet); + if (rc == TPM_RC_SUCCESS) { + rc = TPM2_Packet_Parse(rc, &packet); + + TPM2_Packet_ParseU16(&packet, &out->certifyInfo.size); + TPM2_Packet_ParseBytes(&packet, out->certifyInfo.attestationData, out->certifyInfo.size); + + TPM2_Packet_ParseU16(&packet, &out->signature.sigAlgo); + TPM2_Packet_ParseU16(&packet, &out->signature.signature.any.hashAlg); + } + + TPM2_ReleaseLock(ctx); + } + return rc; +} + + + +/* Utility functions not part of the specification */ + +int TPM2_GetHashDigestSize(TPMI_ALG_HASH hashAlg) +{ + switch (hashAlg) { + case TPM_ALG_SHA1: + return WC_SHA_DIGEST_SIZE; + case TPM_ALG_SHA256: + return WC_SHA256_DIGEST_SIZE; + case TPM_ALG_SHA384: + return WC_SHA384_DIGEST_SIZE; + case TPM_ALG_SHA512: + return WC_SHA512_DIGEST_SIZE; + default: + return 0; + } + return 0; +} + +const char* TPM2_GetAlgName(TPM_ALG_ID alg) +{ + switch (alg) { + case TPM_ALG_RSA: + return "RSA"; + case TPM_ALG_SHA1: + return "SHA1"; + case TPM_ALG_HMAC: + return "HMAC"; + case TPM_ALG_AES: + return "AES"; + case TPM_ALG_MGF1: + return "MGF1"; + case TPM_ALG_KEYEDHASH: + return "KEYEDHASH"; + case TPM_ALG_XOR: + return "XOR"; + case TPM_ALG_SHA256: + return "SHA256"; + case TPM_ALG_SHA384: + return "SHA384"; + case TPM_ALG_SHA512: + return "SHA512"; + case TPM_ALG_NULL: + return "NULL"; + case TPM_ALG_SM3_256: + return "SM3_256"; + case TPM_ALG_SM4: + return "SM4"; + case TPM_ALG_RSASSA: + return "RSASSA"; + case TPM_ALG_RSAES: + return "RSAES"; + case TPM_ALG_RSAPSS: + return "RSAPSS"; + case TPM_ALG_OAEP: + return "OAEP"; + case TPM_ALG_ECDSA: + return "ECDSA"; + case TPM_ALG_ECDH: + return "ECDH"; + case TPM_ALG_ECDAA: + return "ECDAA"; + case TPM_ALG_SM2: + return "SM2"; + case TPM_ALG_ECSCHNORR: + return "ECSCHNORR"; + case TPM_ALG_ECMQV: + return "ECMQV"; + case TPM_ALG_KDF1_SP800_56A: + return "KDF1_SP800_56A"; + case TPM_ALG_KDF2: + return "KDF2"; + case TPM_ALG_KDF1_SP800_108: + return "KDF1_SP800_108"; + case TPM_ALG_ECC: + return "ECC"; + case TPM_ALG_SYMCIPHER: + return "SYMCIPHER"; + case TPM_ALG_CTR: + return "CTR"; + case TPM_ALG_OFB: + return "OFB"; + case TPM_ALG_CBC: + return "CBC"; + case TPM_ALG_CFB: + return "CFB"; + case TPM_ALG_ECB: + return "ECB"; + default: + break; + } + return "Unknown"; +} + + +const char* TPM2_GetRCString(TPM_RC rc) +{ + switch (rc) { + case TPM_RC_SUCCESS: + return "Success"; + case TPM_RC_BAD_TAG: + return "Bad Tag"; + case TPM_RC_BAD_ARG: + return "Bad Argument"; + case TPM_RC_INITIALIZE: + return "TPM not initialized by TPM2_Startup or already initialized"; + case TPM_RC_FAILURE: + return "Commands not being accepted because of a TPM failure"; + case TPM_RC_SEQUENCE: + return "Improper use of a sequence handle"; + case TPM_RC_DISABLED: + return "The command is disabled"; + case TPM_RC_EXCLUSIVE: + return "Command failed because audit sequence required exclusivity"; + case TPM_RC_AUTH_TYPE: + return "Authorization handle is not correct for command"; + case TPM_RC_AUTH_MISSING: + return "Command requires an authorization session for handle and " + "it is not present"; + case TPM_RC_POLICY: + return "Policy failure in math operation or an invalid authPolicy " + "value"; + case TPM_RC_PCR: + return "PCR check fail"; + case TPM_RC_PCR_CHANGED: + return "PCR have changed since checked"; + case TPM_RC_UPGRADE: + return "Indicates that the TPM is in field upgrade mode"; + case TPM_RC_TOO_MANY_CONTEXTS: + return "Context ID counter is at maximum"; + case TPM_RC_AUTH_UNAVAILABLE: + return "The authValue or authPolicy is not available for selected " + "entity"; + case TPM_RC_REBOOT: + return "A _TPM_Init and Startup(CLEAR) is required before the TPM " + "can resume operation"; + case TPM_RC_UNBALANCED: + return "The protection algorithms (hash and symmetric) are not " + "reasonably balanced"; + case TPM_RC_COMMAND_SIZE: + return "Command commandSize value is inconsistent with contents of " + "the command buffer"; + case TPM_RC_COMMAND_CODE: + return "Command code not supported"; + case TPM_RC_AUTHSIZE: + return "The value of authorizationSize is out of range or the " + "number of octets in the Authorization Area is greater than " + "required"; + case TPM_RC_AUTH_CONTEXT: + return "Use of an authorization session with a context command or " + "another command that cannot have an authorization session"; + case TPM_RC_NV_RANGE: + return "NV offset+size is out of range"; + case TPM_RC_NV_SIZE: + return "Requested allocation size is larger than allowed"; + case TPM_RC_NV_LOCKED: + return "NV access locked"; + case TPM_RC_NV_AUTHORIZATION: + return "NV access authorization fails in command actions"; + case TPM_RC_NV_UNINITIALIZED: + return "An NV Index is used before being initialized or the state " + "saved by TPM2_Shutdown(STATE) could not be restored"; + case TPM_RC_NV_SPACE: + return "Insufficient space for NV allocation"; + case TPM_RC_NV_DEFINED: + return "NV Index or persistent object already defined"; + case TPM_RC_BAD_CONTEXT: + return "Context in TPM2_ContextLoad() is not valid"; + case TPM_RC_CPHASH: + return "The cpHash value already set or not correct for use"; + case TPM_RC_PARENT: + return "Handle for parent is not a valid parent"; + case TPM_RC_NEEDS_TEST: + return "Some function needs testing"; + case TPM_RC_NO_RESULT: + return "Cannot process a request due to an unspecified problem"; + case TPM_RC_SENSITIVE: + return "The sensitive area did not unmarshal correctly after " + "decryption"; + case TPM_RC_ASYMMETRIC: + return "Asymmetric algorithm not supported or not correct"; + case TPM_RC_ATTRIBUTES: + return "Inconsistent attributes"; + case TPM_RC_HASH: + return "Hash algorithm not supported or not appropriate"; + case TPM_RC_VALUE: + return "Value is out of range or is not correct for the context"; + case TPM_RC_HIERARCHY: + return "Hierarchy is not enabled or is not correct for the use"; + case TPM_RC_KEY_SIZE: + return "Key size is not supported"; + case TPM_RC_MGF: + return "Mask generation function not supported"; + case TPM_RC_MODE: + return "Mode of operation not supported"; + case TPM_RC_TYPE: + return "The type of the value is not appropriate for the use"; + case TPM_RC_HANDLE: + return "The handle is not correct for the use"; + case TPM_RC_KDF: + return "Unsupported key derivation function or function not " + "appropriate for use"; + case TPM_RC_RANGE: + return "Value was out of allowed range"; + case TPM_RC_AUTH_FAIL: + return "The authorization HMAC check failed and DA counter " + "incremented"; + case TPM_RC_NONCE: + return "Invalid nonce size or nonce value mismatch"; + case TPM_RC_PP: + return "Authorization requires assertion of PP"; + case TPM_RC_SCHEME: + return "Unsupported or incompatible scheme"; + case TPM_RC_SIZE: + return "Structure is the wrong size"; + case TPM_RC_SYMMETRIC: + return "Unsupported symmetric algorithm or key size, or not " + "appropriate for instance"; + case TPM_RC_TAG: + return "Incorrect structure tag"; + case TPM_RC_SELECTOR: + return "Union selector is incorrect"; + case TPM_RC_INSUFFICIENT: + return "The TPM was unable to unmarshal a value because there were " + "not enough octets in the input buffer"; + case TPM_RC_SIGNATURE: + return "The signature is not valid"; + case TPM_RC_KEY: + return "Key fields are not compatible with the selected use"; + case TPM_RC_POLICY_FAIL: + return "A policy check failed"; + case TPM_RC_INTEGRITY: + return "Integrity check failed"; + case TPM_RC_TICKET: + return "Invalid ticket"; + case TPM_RC_RESERVED_BITS: + return "Reserved bits not set to zero as required"; + case TPM_RC_BAD_AUTH: + return "Authorization failure without DA implications"; + case TPM_RC_EXPIRED: + return "The policy has expired"; + case TPM_RC_POLICY_CC: + return "The commandCode in the policy is not the commandCode of " + "the command or the command code in a policy command " + "references a command that is not implemented"; + case TPM_RC_BINDING: + return "Public and sensitive portions of an object are not " + "cryptographically bound"; + case TPM_RC_CURVE: + return "Curve not supported"; + case TPM_RC_ECC_POINT: + return "Point is not on the required curve"; + case TPM_RC_CONTEXT_GAP: + return "Gap for context ID is too large"; + case TPM_RC_OBJECT_MEMORY: + return "Out of memory for object contexts"; + case TPM_RC_SESSION_MEMORY: + return "Out of memory for session contexts"; + case TPM_RC_MEMORY: + return "Out of shared object/session memory or need space for " + "internal operations"; + case TPM_RC_SESSION_HANDLES: + return "Out of session handles; a session must be flushed before " + "a new session may be created"; + case TPM_RC_OBJECT_HANDLES: + return "Out of object handles"; + case TPM_RC_LOCALITY: + return "Bad locality"; + case TPM_RC_YIELDED: + return "The TPM has suspended operation on the command"; + case TPM_RC_CANCELED: + return "The command was canceled"; + case TPM_RC_TESTING: + return "TPM is performing self-tests"; + case TPM_RC_NV_RATE: + return "The TPM is rate-limiting accesses to prevent wearout of NV"; + case TPM_RC_LOCKOUT: + return "Authorizations for objects subject to DA protection are not" + " allowed at this time because the TPM is in DA lockout mode"; + case TPM_RC_RETRY: + return "The TPM was not able to start the command"; + case TPM_RC_NV_UNAVAILABLE: + return "The command may require writing of NV and NV is not current" + " accessible"; + case TPM_RC_NOT_USED: + return "This value is reserved and shall not be returned by the " + "TPM"; + default: + break; + } + return "Unknown"; +} + +void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, int pcrIndex) +{ + if (pcr) { + pcr->count = 1; + pcr->pcrSelections[0].hash = alg; + pcr->pcrSelections[0].sizeofSelect = PCR_SELECT_MIN; + XMEMSET(pcr->pcrSelections[0].pcrSelect, 0, PCR_SELECT_MIN); + pcr->pcrSelections[0].pcrSelect[pcrIndex >> 3] = (1 << (pcrIndex & 0x7)); + } +} diff --git a/wolftpm/include.am b/wolftpm/include.am new file mode 100644 index 0000000..f69a7c4 --- /dev/null +++ b/wolftpm/include.am @@ -0,0 +1,8 @@ +# vim:ft=automake +# All paths should be given relative to the root +# + +nobase_include_HEADERS+= \ + wolftpm/tpm2.h \ + wolftpm/version.h \ + wolftpm/visibility.h diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h new file mode 100644 index 0000000..6e33559 --- /dev/null +++ b/wolftpm/tpm2.h @@ -0,0 +1,2884 @@ +/* tpm2.h + * + * Copyright (C) 2006-2017 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef __TPM2_H__ +#define __TPM2_H__ + +#include +#include +#include +#include + +#ifndef MAX_SPI_FRAMESIZE +#define MAX_SPI_FRAMESIZE 64 +#endif + +#ifndef TPM_TIMEOUT_TRIES +#define TPM_TIMEOUT_TRIES 100000 +#endif + +#ifndef MAX_SYM_BLOCK_SIZE +#define MAX_SYM_BLOCK_SIZE 20 +#endif +#ifndef MAX_SYM_KEY_BYTES +#define MAX_SYM_KEY_BYTES 256 +#endif +#ifndef LABEL_MAX_BUFFER +#define LABEL_MAX_BUFFER 128 +#endif +#ifndef MAX_RSA_KEY_BITS +#define MAX_RSA_KEY_BITS 2048 +#endif +#ifndef MAX_RSA_KEY_BYTES +#define MAX_RSA_KEY_BYTES ((MAX_RSA_KEY_BITS/8)*2) +#endif +#ifndef MAX_ECC_KEY_BYTES +#define MAX_ECC_KEY_BYTES (MAX_ECC_BYTES*2) +#endif + +/* Implementation Specific Values */ +#ifndef BUFFER_ALIGNMENT +#define BUFFER_ALIGNMENT 4 +#endif +#ifndef IMPLEMENTATION_PCR +#define IMPLEMENTATION_PCR 24 +#endif +#ifndef PLATFORM_PCR +#define PLATFORM_PCR 24 +#endif +#ifndef DRTM_PCR +#define DRTM_PCR 17 +#endif +#ifndef HCRTM_PCR +#define HCRTM_PCR 0 +#endif +#ifndef NUM_LOCALITIES +#define NUM_LOCALITIES 1 +#endif +#ifndef MAX_HANDLE_NUM +#define MAX_HANDLE_NUM 3 +#endif +#ifndef MAX_ACTIVE_SESSIONS +#define MAX_ACTIVE_SESSIONS 64 +#endif +#ifndef MAX_LOADED_SESSIONS +#define MAX_LOADED_SESSIONS 3 +#endif +#ifndef MAX_SESSION_NUM +#define MAX_SESSION_NUM 3 +#endif +#ifndef MAX_LOADED_OBJECTS +#define MAX_LOADED_OBJECTS 3 +#endif +#ifndef MIN_EVICT_OBJECTS +#define MIN_EVICT_OBJECTS 2 +#endif +#ifndef PCR_SELECT_MIN +#define PCR_SELECT_MIN ((PLATFORM_PCR+7)/8) +#endif +#ifndef PCR_SELECT_MAX +#define PCR_SELECT_MAX ((IMPLEMENTATION_PCR+7)/8) +#endif +#ifndef MAX_CONTEXT_SIZE +#define MAX_CONTEXT_SIZE 2048 +#endif +#ifndef MAX_DIGEST_BUFFER +#define MAX_DIGEST_BUFFER 1024 +#endif +#ifndef MAX_NV_INDEX_SIZE +#define MAX_NV_INDEX_SIZE 2048 +#endif +#ifndef MAX_NV_BUFFER_SIZE +#define MAX_NV_BUFFER_SIZE 1024 +#endif +#ifndef MAX_CAP_BUFFER +#define MAX_CAP_BUFFER 1024 +#endif +#ifndef NV_MEMORY_SIZE +#define NV_MEMORY_SIZE 16384 +#endif +#ifndef NUM_STATIC_PCR +#define NUM_STATIC_PCR 16 +#endif +#ifndef MAX_ALG_LIST_SIZE +#define MAX_ALG_LIST_SIZE 64 +#endif +#ifndef TIMER_PRESCALE +#define TIMER_PRESCALE 100000 +#endif +#ifndef PRIMARY_SEED_SIZE +#define PRIMARY_SEED_SIZE 32 +#endif +#ifndef CONTEXT_ENCRYPT_ALG +#define CONTEXT_ENCRYPT_ALG TPM_ALG_AES +#endif +#ifndef CONTEXT_ENCRYPT_KEY_BITS +#define CONTEXT_ENCRYPT_KEY_BITS MAX_SYM_KEY_BITS +#endif +#ifndef CONTEXT_ENCRYPT_KEY_BYTES +#define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS+7 )/8) +#endif +#ifndef CONTEXT_INTEGRITY_HASH_ALG +#define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256 +#endif +#ifndef CONTEXT_INTEGRITY_HASH_SIZE +#define CONTEXT_INTEGRITY_HASH_SIZE SHA256_DIGEST_SIZE +#endif +#ifndef PROOF_SIZE +#define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE +#endif +#ifndef NV_CLOCK_UPDATE_INTERVAL +#define NV_CLOCK_UPDATE_INTERVAL 12 +#endif +#ifndef NUM_POLICY_PCR +#define NUM_POLICY_PCR 1 +#endif +#ifndef MAX_COMMAND_SIZE +#define MAX_COMMAND_SIZE 4096 +#endif +#ifndef MAX_RESPONSE_SIZE +#define MAX_RESPONSE_SIZE 4096 +#endif +#ifndef ORDERLY_BITS +#define ORDERLY_BITS 8 +#endif +#ifndef MAX_ORDERLY_COUNT +#define MAX_ORDERLY_COUNT ((1 << ORDERLY_BITS) - 1) +#endif +#ifndef ALG_ID_FIRST +#define ALG_ID_FIRST TPM_ALG_FIRST +#endif +#ifndef ALG_ID_LAST +#define ALG_ID_LAST TPM_ALG_LAST +#endif +#ifndef MAX_SYM_DATA +#define MAX_SYM_DATA 128 +#endif +#ifndef MAX_RNG_ENTROPY_SIZE +#define MAX_RNG_ENTROPY_SIZE 64 +#endif +#ifndef RAM_INDEX_SPACE +#define RAM_INDEX_SPACE 512 +#endif +#ifndef RSA_DEFAULT_PUBLIC_EXPONENT +#define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001 +#endif +#ifndef ENABLE_PCR_NO_INCREMENT +#define ENABLE_PCR_NO_INCREMENT 1 +#endif +#ifndef CRT_FORMAT_RSA +#define CRT_FORMAT_RSA 1 +#endif +#ifndef PRIVATE_VENDOR_SPECIFIC_BYTES +#define PRIVATE_VENDOR_SPECIFIC_BYTES ((MAX_RSA_KEY_BYTES/2) * (3 + CRT_FORMAT_RSA * 2)) +#endif +#ifndef MAX_CAP_CC +#define MAX_CAP_CC ((TPM_CC_LAST - TPM_CC_FIRST) + 1) +#endif +#ifndef MAX_CAP_DATA +#define MAX_CAP_DATA (MAX_CAP_BUFFER - sizeof(TPM_CAP) - sizeof(UINT32)) +#endif +#ifndef MAX_CAP_HANDLES +#define MAX_CAP_HANDLES (MAX_CAP_DATA / sizeof(TPM_HANDLE)) +#endif +#ifndef HASH_COUNT +#define HASH_COUNT (2) /* SHA1 and SHA256 */ +#endif +#ifndef MAX_CAP_ALGS +#define MAX_CAP_ALGS (MAX_CAP_DATA / sizeof(TPMS_ALG_PROPERTY)) +#endif +#ifndef MAX_TPM_PROPERTIES +#define MAX_TPM_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PROPERTY)) +#endif +#ifndef MAX_PCR_PROPERTIES +#define MAX_PCR_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT)) +#endif +#ifndef MAX_ECC_CURVES +#define MAX_ECC_CURVES (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE)) +#endif +#ifndef MAX_TAGGED_POLICIES +#define MAX_TAGGED_POLICIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_POLICY)) +#endif + + +/* Types */ +#include +typedef uint8_t UINT8; +typedef uint8_t BYTE; +typedef int8_t INT8; +typedef int BOOL; +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint32_t UINT32; +typedef int32_t INT32; +typedef uint64_t UINT64; +typedef int64_t INT64; + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef YES +#define YES 1 +#endif +#ifndef NO +#define NO 0 +#endif +#ifndef SET +#define SET 1 +#endif +#ifndef CLEAR +#define CLEAR 0 +#endif + +typedef UINT32 TPM_ALGORITHM_ID; +typedef UINT32 TPM_MODIFIER_INDICATOR; +typedef UINT32 TPM_AUTHORIZATION_SIZE; +typedef UINT32 TPM_PARAMETER_SIZE; +typedef UINT16 TPM_KEY_SIZE; +typedef UINT16 TPM_KEY_BITS; +typedef UINT32 TPM_GENERATED; + + +/* ---------------------------------------------------------------------------*/ +/* ENUMERATIONS */ +/* ---------------------------------------------------------------------------*/ + +enum { + TPM_SPEC_FAMILY = 0x322E3000, + TPM_SPEC_LEVEL = 0, + TPM_SPEC_VERSION = 138, + TPM_SPEC_YEAR = 2016, + TPM_SPEC_DAY_OF_YEAR = 273, + + TPM_GENERATED_VALUE = 0xff544347, +}; + + +typedef enum { + TPM_ALG_ERROR = 0x0000, + TPM_ALG_RSA = 0x0001, + TPM_ALG_SHA = 0x0004, + TPM_ALG_SHA1 = TPM_ALG_SHA, + TPM_ALG_HMAC = 0x0005, + TPM_ALG_AES = 0x0006, + TPM_ALG_MGF1 = 0x0007, + TPM_ALG_KEYEDHASH = 0x0008, + TPM_ALG_XOR = 0x000A, + TPM_ALG_SHA256 = 0x000B, + TPM_ALG_SHA384 = 0x000C, + TPM_ALG_SHA512 = 0x000D, + TPM_ALG_NULL = 0x0010, + TPM_ALG_SM3_256 = 0x0012, + TPM_ALG_SM4 = 0x0013, + TPM_ALG_RSASSA = 0x0014, + TPM_ALG_RSAES = 0x0015, + TPM_ALG_RSAPSS = 0x0016, + TPM_ALG_OAEP = 0x0017, + TPM_ALG_ECDSA = 0x0018, + TPM_ALG_ECDH = 0x0019, + TPM_ALG_ECDAA = 0x001A, + TPM_ALG_SM2 = 0x001B, + TPM_ALG_ECSCHNORR = 0x001C, + TPM_ALG_ECMQV = 0x001D, + TPM_ALG_KDF1_SP800_56A = 0x0020, + TPM_ALG_KDF2 = 0x0021, + TPM_ALG_KDF1_SP800_108 = 0x0022, + TPM_ALG_ECC = 0x0023, + TPM_ALG_SYMCIPHER = 0x0025, + TPM_ALG_CAMELLIA = 0x0026, + TPM_ALG_CTR = 0x0040, + TPM_ALG_OFB = 0x0041, + TPM_ALG_CBC = 0x0042, + TPM_ALG_CFB = 0x0043, + TPM_ALG_ECB = 0x0044, +} TPM_ALG_ID_T; +typedef UINT16 TPM_ALG_ID; + +typedef enum { + TPM_ECC_NONE = 0x0000, + TPM_ECC_NIST_P192 = 0x0001, + TPM_ECC_NIST_P224 = 0x0002, + TPM_ECC_NIST_P256 = 0x0003, + TPM_ECC_NIST_P384 = 0x0004, + TPM_ECC_NIST_P521 = 0x0005, + TPM_ECC_BN_P256 = 0x0010, + TPM_ECC_BN_P638 = 0x0011, + TPM_ECC_SM2_P256 = 0x0020, +} TPM_ECC_CURVE_T; +typedef UINT16 TPM_ECC_CURVE; + +/* Command Codes */ +typedef enum { + TPM_CC_FIRST = 0x0000011F, + TPM_CC_NV_UndefineSpaceSpecial = TPM_CC_FIRST, + TPM_CC_EvictControl = 0x00000120, + TPM_CC_HierarchyControl = 0x00000121, + TPM_CC_NV_UndefineSpace = 0x00000122, + TPM_CC_ChangeEPS = 0x00000124, + TPM_CC_ChangePPS = 0x00000125, + TPM_CC_Clear = 0x00000126, + TPM_CC_ClearControl = 0x00000127, + TPM_CC_ClockSet = 0x00000128, + TPM_CC_HierarchyChangeAuth = 0x00000129, + TPM_CC_NV_DefineSpace = 0x0000012A, + TPM_CC_PCR_Allocate = 0x0000012B, + TPM_CC_PCR_SetAuthPolicy = 0x0000012C, + TPM_CC_PP_Commands = 0x0000012D, + TPM_CC_SetPrimaryPolicy = 0x0000012E, + TPM_CC_FieldUpgradeStart = 0x0000012F, + TPM_CC_ClockRateAdjust = 0x00000130, + TPM_CC_CreatePrimary = 0x00000131, + TPM_CC_NV_GlobalWriteLock = 0x00000132, + TPM_CC_GetCommandAuditDigest = 0x00000133, + TPM_CC_NV_Increment = 0x00000134, + TPM_CC_NV_SetBits = 0x00000135, + TPM_CC_NV_Extend = 0x00000136, + TPM_CC_NV_Write = 0x00000137, + TPM_CC_NV_WriteLock = 0x00000138, + TPM_CC_DictionaryAttackLockReset = 0x00000139, + TPM_CC_DictionaryAttackParameters = 0x0000013A, + TPM_CC_NV_ChangeAuth = 0x0000013B, + TPM_CC_PCR_Event = 0x0000013C, + TPM_CC_PCR_Reset = 0x0000013D, + TPM_CC_SequenceComplete = 0x0000013E, + TPM_CC_SetAlgorithmSet = 0x0000013F, + TPM_CC_SetCommandCodeAuditStatus = 0x00000140, + TPM_CC_FieldUpgradeData = 0x00000141, + TPM_CC_IncrementalSelfTest = 0x00000142, + TPM_CC_SelfTest = 0x00000143, + TPM_CC_Startup = 0x00000144, + TPM_CC_Shutdown = 0x00000145, + TPM_CC_StirRandom = 0x00000146, + TPM_CC_ActivateCredential = 0x00000147, + TPM_CC_Certify = 0x00000148, + TPM_CC_PolicyNV = 0x00000149, + TPM_CC_CertifyCreation = 0x0000014A, + TPM_CC_Duplicate = 0x0000014B, + TPM_CC_GetTime = 0x0000014C, + TPM_CC_GetSessionAuditDigest = 0x0000014D, + TPM_CC_NV_Read = 0x0000014E, + TPM_CC_NV_ReadLock = 0x0000014F, + TPM_CC_ObjectChangeAuth = 0x00000150, + TPM_CC_PolicySecret = 0x00000151, + TPM_CC_Rewrap = 0x00000152, + TPM_CC_Create = 0x00000153, + TPM_CC_ECDH_ZGen = 0x00000154, + TPM_CC_HMAC = 0x00000155, + TPM_CC_Import = 0x00000156, + TPM_CC_Load = 0x00000157, + TPM_CC_Quote = 0x00000158, + TPM_CC_RSA_Decrypt = 0x00000159, + TPM_CC_HMAC_Start = 0x0000015B, + TPM_CC_SequenceUpdate = 0x0000015C, + TPM_CC_Sign = 0x0000015D, + TPM_CC_Unseal = 0x0000015E, + TPM_CC_PolicySigned = 0x00000160, + TPM_CC_ContextLoad = 0x00000161, + TPM_CC_ContextSave = 0x00000162, + TPM_CC_ECDH_KeyGen = 0x00000163, + TPM_CC_EncryptDecrypt = 0x00000164, + TPM_CC_FlushContext = 0x00000165, + TPM_CC_LoadExternal = 0x00000166, + TPM_CC_MakeCredential = 0x00000167, + TPM_CC_NV_ReadPublic = 0x00000168, + TPM_CC_PolicyAuthorize = 0x0000016A, + TPM_CC_PolicyAuthValue = 0x0000016B, + TPM_CC_PolicyCommandCode = 0x0000016C, + TPM_CC_PolicyCounterTimer = 0x0000016D, + TPM_CC_PolicyCpHash = 0x0000016E, + TPM_CC_PolicyLocality = 0x0000016F, + TPM_CC_PolicyNameHash = 0x00000170, + TPM_CC_PolicyOR = 0x00000171, + TPM_CC_PolicyTicket = 0x00000172, + TPM_CC_ReadPublic = 0x00000173, + TPM_CC_RSA_Encrypt = 0x00000174, + TPM_CC_StartAuthSession = 0x00000176, + TPM_CC_VerifySignature = 0x00000177, + TPM_CC_ECC_Parameters = 0x00000178, + TPM_CC_FirmwareRead = 0x00000179, + TPM_CC_GetCapability = 0x0000017A, + TPM_CC_GetRandom = 0x0000017B, + TPM_CC_GetTestResult = 0x0000017C, + TPM_CC_Hash = 0x0000017D, + TPM_CC_PCR_Read = 0x0000017E, + TPM_CC_PolicyPCR = 0x0000017F, + TPM_CC_PolicyRestart = 0x00000180, + TPM_CC_ReadClock = 0x00000181, + TPM_CC_PCR_Extend = 0x00000182, + TPM_CC_PCR_SetAuthValue = 0x00000183, + TPM_CC_NV_Certify = 0x00000184, + TPM_CC_EventSequenceComplete = 0x00000185, + TPM_CC_HashSequenceStart = 0x00000186, + TPM_CC_PolicyPhysicalPresence = 0x00000187, + TPM_CC_PolicyDuplicationSelect = 0x00000188, + TPM_CC_PolicyGetDigest = 0x00000189, + TPM_CC_TestParms = 0x0000018A, + TPM_CC_Commit = 0x0000018B, + TPM_CC_PolicyPassword = 0x0000018C, + TPM_CC_ZGen_2Phase = 0x0000018D, + TPM_CC_EC_Ephemeral = 0x0000018E, + TPM_CC_PolicyNvWritten = 0x0000018F, + TPM_CC_PolicyTemplate = 0x00000190, + TPM_CC_CreateLoaded = 0x00000191, + TPM_CC_PolicyAuthorizeNV = 0x00000192, + TPM_CC_EncryptDecrypt2 = 0x00000193, + TPM_CC_LAST = TPM_CC_EncryptDecrypt2, + + CC_VEND = 0x20000000, + TPM_CC_Vendor_TCG_Test = CC_VEND + 0x0000, +} TPM_CC_T; +typedef UINT32 TPM_CC; + +/* Response Codes */ +typedef enum { + TPM_RC_SUCCESS = 0x000, + TPM_RC_BAD_TAG = 0x01E, + TPM_RC_BAD_ARG = 0x01D, + + RC_VER1 = 0x100, + TPM_RC_INITIALIZE = RC_VER1 + 0x000, + TPM_RC_FAILURE = RC_VER1 + 0x001, + TPM_RC_SEQUENCE = RC_VER1 + 0x003, + TPM_RC_PRIVATE = RC_VER1 + 0x00B, + TPM_RC_HMAC = RC_VER1 + 0x019, + TPM_RC_DISABLED = RC_VER1 + 0x020, + TPM_RC_EXCLUSIVE = RC_VER1 + 0x021, + TPM_RC_AUTH_TYPE = RC_VER1 + 0x024, + TPM_RC_AUTH_MISSING = RC_VER1 + 0x025, + TPM_RC_POLICY = RC_VER1 + 0x026, + TPM_RC_PCR = RC_VER1 + 0x027, + TPM_RC_PCR_CHANGED = RC_VER1 + 0x028, + TPM_RC_UPGRADE = RC_VER1 + 0x02D, + TPM_RC_TOO_MANY_CONTEXTS = RC_VER1 + 0x02E, + TPM_RC_AUTH_UNAVAILABLE = RC_VER1 + 0x02F, + TPM_RC_REBOOT = RC_VER1 + 0x030, + TPM_RC_UNBALANCED = RC_VER1 + 0x031, + TPM_RC_COMMAND_SIZE = RC_VER1 + 0x042, + TPM_RC_COMMAND_CODE = RC_VER1 + 0x043, + TPM_RC_AUTHSIZE = RC_VER1 + 0x044, + TPM_RC_AUTH_CONTEXT = RC_VER1 + 0x045, + TPM_RC_NV_RANGE = RC_VER1 + 0x046, + TPM_RC_NV_SIZE = RC_VER1 + 0x047, + TPM_RC_NV_LOCKED = RC_VER1 + 0x048, + TPM_RC_NV_AUTHORIZATION = RC_VER1 + 0x049, + TPM_RC_NV_UNINITIALIZED = RC_VER1 + 0x04A, + TPM_RC_NV_SPACE = RC_VER1 + 0x04B, + TPM_RC_NV_DEFINED = RC_VER1 + 0x04C, + TPM_RC_BAD_CONTEXT = RC_VER1 + 0x050, + TPM_RC_CPHASH = RC_VER1 + 0x051, + TPM_RC_PARENT = RC_VER1 + 0x052, + TPM_RC_NEEDS_TEST = RC_VER1 + 0x053, + TPM_RC_NO_RESULT = RC_VER1 + 0x054, + TPM_RC_SENSITIVE = RC_VER1 + 0x055, + RC_MAX_FM0 = RC_VER1 + 0x07F, + + RC_FMT1 = 0x080, + TPM_RC_ASYMMETRIC = RC_FMT1 + 0x001, + TPM_RC_ATTRIBUTES = RC_FMT1 + 0x002, + TPM_RC_HASH = RC_FMT1 + 0x003, + TPM_RC_VALUE = RC_FMT1 + 0x004, + TPM_RC_HIERARCHY = RC_FMT1 + 0x005, + TPM_RC_KEY_SIZE = RC_FMT1 + 0x007, + TPM_RC_MGF = RC_FMT1 + 0x008, + TPM_RC_MODE = RC_FMT1 + 0x009, + TPM_RC_TYPE = RC_FMT1 + 0x00A, + TPM_RC_HANDLE = RC_FMT1 + 0x00B, + TPM_RC_KDF = RC_FMT1 + 0x00C, + TPM_RC_RANGE = RC_FMT1 + 0x00D, + TPM_RC_AUTH_FAIL = RC_FMT1 + 0x00E, + TPM_RC_NONCE = RC_FMT1 + 0x00F, + TPM_RC_PP = RC_FMT1 + 0x010, + TPM_RC_SCHEME = RC_FMT1 + 0x012, + TPM_RC_SIZE = RC_FMT1 + 0x015, + TPM_RC_SYMMETRIC = RC_FMT1 + 0x016, + TPM_RC_TAG = RC_FMT1 + 0x017, + TPM_RC_SELECTOR = RC_FMT1 + 0x018, + TPM_RC_INSUFFICIENT = RC_FMT1 + 0x01A, + TPM_RC_SIGNATURE = RC_FMT1 + 0x01B, + TPM_RC_KEY = RC_FMT1 + 0x01C, + TPM_RC_POLICY_FAIL = RC_FMT1 + 0x01D, + TPM_RC_INTEGRITY = RC_FMT1 + 0x01F, + TPM_RC_TICKET = RC_FMT1 + 0x020, + TPM_RC_RESERVED_BITS = RC_FMT1 + 0x021, + TPM_RC_BAD_AUTH = RC_FMT1 + 0x022, + TPM_RC_EXPIRED = RC_FMT1 + 0x023, + TPM_RC_POLICY_CC = RC_FMT1 + 0x024, + TPM_RC_BINDING = RC_FMT1 + 0x025, + TPM_RC_CURVE = RC_FMT1 + 0x026, + TPM_RC_ECC_POINT = RC_FMT1 + 0x027, + + RC_WARN = 0x900, + TPM_RC_CONTEXT_GAP = RC_WARN + 0x001, + TPM_RC_OBJECT_MEMORY = RC_WARN + 0x002, + TPM_RC_SESSION_MEMORY = RC_WARN + 0x003, + TPM_RC_MEMORY = RC_WARN + 0x004, + TPM_RC_SESSION_HANDLES = RC_WARN + 0x005, + TPM_RC_OBJECT_HANDLES = RC_WARN + 0x006, + TPM_RC_LOCALITY = RC_WARN + 0x007, + TPM_RC_YIELDED = RC_WARN + 0x008, + TPM_RC_CANCELED = RC_WARN + 0x009, + TPM_RC_TESTING = RC_WARN + 0x00A, + TPM_RC_REFERENCE_H0 = RC_WARN + 0x010, + TPM_RC_REFERENCE_H1 = RC_WARN + 0x011, + TPM_RC_REFERENCE_H2 = RC_WARN + 0x012, + TPM_RC_REFERENCE_H3 = RC_WARN + 0x013, + TPM_RC_REFERENCE_H4 = RC_WARN + 0x014, + TPM_RC_REFERENCE_H5 = RC_WARN + 0x015, + TPM_RC_REFERENCE_H6 = RC_WARN + 0x016, + TPM_RC_REFERENCE_S0 = RC_WARN + 0x018, + TPM_RC_REFERENCE_S1 = RC_WARN + 0x019, + TPM_RC_REFERENCE_S2 = RC_WARN + 0x01A, + TPM_RC_REFERENCE_S3 = RC_WARN + 0x01B, + TPM_RC_REFERENCE_S4 = RC_WARN + 0x01C, + TPM_RC_REFERENCE_S5 = RC_WARN + 0x01D, + TPM_RC_REFERENCE_S6 = RC_WARN + 0x01E, + TPM_RC_NV_RATE = RC_WARN + 0x020, + TPM_RC_LOCKOUT = RC_WARN + 0x021, + TPM_RC_RETRY = RC_WARN + 0x022, + TPM_RC_NV_UNAVAILABLE = RC_WARN + 0x023, + TPM_RC_NOT_USED = RC_WARN + 0x7F, + + TPM_RC_H = 0x000, + TPM_RC_P = 0x040, + TPM_RC_S = 0x800, + TPM_RC_1 = 0x100, + TPM_RC_2 = 0x200, + TPM_RC_3 = 0x300, + TPM_RC_4 = 0x400, + TPM_RC_5 = 0x500, + TPM_RC_6 = 0x600, + TPM_RC_7 = 0x700, + TPM_RC_8 = 0x800, + TPM_RC_9 = 0x900, + TPM_RC_A = 0xA00, + TPM_RC_B = 0xB00, + TPM_RC_C = 0xC00, + TPM_RC_D = 0xD00, + TPM_RC_E = 0xE00, + TPM_RC_F = 0xF00, + TPM_RC_N_MASK = 0xF00, +} TPM_RC_T; +typedef UINT16 TPM_RC; + +typedef enum { + TPM_CLOCK_COARSE_SLOWER = -3, + TPM_CLOCK_MEDIUM_SLOWER = -2, + TPM_CLOCK_FINE_SLOWER = -1, + TPM_CLOCK_NO_CHANGE = 0, + TPM_CLOCK_FINE_FASTER = 1, + TPM_CLOCK_MEDIUM_FASTER = 2, + TPM_CLOCK_COARSE_FASTER = 3, +} TPM_CLOCK_ADJUST_T; +typedef UINT8 TPM_CLOCK_ADJUST; + +/* EA Arithmetic Operands */ +typedef enum { + TPM_EO_EQ = 0x0000, + TPM_EO_NEQ = 0x0001, + TPM_EO_SIGNED_GT = 0x0002, + TPM_EO_UNSIGNED_GT = 0x0003, + TPM_EO_SIGNED_LT = 0x0004, + TPM_EO_UNSIGNED_LT = 0x0005, + TPM_EO_SIGNED_GE = 0x0006, + TPM_EO_UNSIGNED_GE = 0x0007, + TPM_EO_SIGNED_LE = 0x0008, + TPM_EO_UNSIGNED_LE = 0x0009, + TPM_EO_BITSET = 0x000A, + TPM_EO_BITCLEAR = 0x000B, +} TPM_EO_T; +typedef UINT16 TPM_EO; + +/* Structure Tags */ +typedef enum { + TPM_ST_RSP_COMMAND = 0x00C4, + TPM_ST_NULL = 0X8000, + TPM_ST_NO_SESSIONS = 0x8001, + TPM_ST_SESSIONS = 0x8002, + TPM_ST_ATTEST_NV = 0x8014, + TPM_ST_ATTEST_COMMAND_AUDIT = 0x8015, + TPM_ST_ATTEST_SESSION_AUDIT = 0x8016, + TPM_ST_ATTEST_CERTIFY = 0x8017, + TPM_ST_ATTEST_QUOTE = 0x8018, + TPM_ST_ATTEST_TIME = 0x8019, + TPM_ST_ATTEST_CREATION = 0x801A, + TPM_ST_CREATION = 0x8021, + TPM_ST_VERIFIED = 0x8022, + TPM_ST_AUTH_SECRET = 0x8023, + TPM_ST_HASHCHECK = 0x8024, + TPM_ST_AUTH_SIGNED = 0x8025, + TPM_ST_FU_MANIFEST = 0x8029, +} TPM_ST_T; +typedef UINT16 TPM_ST; + +/* Session Type */ +typedef enum { + TPM_SE_HMAC = 0x00, + TPM_SE_POLICY = 0x01, + TPM_SE_TRIAL = 0x03, +} TPM_SE_T; +typedef UINT8 TPM_SE; + + +/* Startup Type */ +typedef enum { + TPM_SU_CLEAR = 0x0000, + TPM_SU_STATE = 0x0001, +} TPM_SU_T; +typedef UINT16 TPM_SU; + +/* Capabilities */ +typedef enum { + TPM_CAP_FIRST = 0x00000000, + TPM_CAP_ALGS = TPM_CAP_FIRST, + TPM_CAP_HANDLES = 0x00000001, + TPM_CAP_COMMANDS = 0x00000002, + TPM_CAP_PP_COMMANDS = 0x00000003, + TPM_CAP_AUDIT_COMMANDS = 0x00000004, + TPM_CAP_PCRS = 0x00000005, + TPM_CAP_TPM_PROPERTIES = 0x00000006, + TPM_CAP_PCR_PROPERTIES = 0x00000007, + TPM_CAP_ECC_CURVES = 0x00000008, + TPM_CAP_LAST = TPM_CAP_ECC_CURVES, + + TPM_CAP_VENDOR_PROPERTY = 0x00000100, +} TPM_CAP_T; +typedef UINT32 TPM_CAP; + +/* Property Tag */ +typedef enum { + TPM_PT_NONE = 0x00000000, + PT_GROUP = 0x00000100, + + PT_FIXED = PT_GROUP * 1, + TPM_PT_FAMILY_INDICATOR = PT_FIXED + 0, + TPM_PT_LEVEL = PT_FIXED + 1, + TPM_PT_REVISION = PT_FIXED + 2, + TPM_PT_DAY_OF_YEAR = PT_FIXED + 3, + TPM_PT_YEAR = PT_FIXED + 4, + TPM_PT_MANUFACTURER = PT_FIXED + 5, + TPM_PT_VENDOR_STRING_1 = PT_FIXED + 6, + TPM_PT_VENDOR_STRING_2 = PT_FIXED + 7, + TPM_PT_VENDOR_STRING_3 = PT_FIXED + 8, + TPM_PT_VENDOR_STRING_4 = PT_FIXED + 9, + TPM_PT_VENDOR_TPM_TYPE = PT_FIXED + 10, + TPM_PT_FIRMWARE_VERSION_1 = PT_FIXED + 11, + TPM_PT_FIRMWARE_VERSION_2 = PT_FIXED + 12, + TPM_PT_INPUT_BUFFER = PT_FIXED + 13, + TPM_PT_HR_TRANSIENT_MIN = PT_FIXED + 14, + TPM_PT_HR_PERSISTENT_MIN = PT_FIXED + 15, + TPM_PT_HR_LOADED_MIN = PT_FIXED + 16, + TPM_PT_ACTIVE_SESSIONS_MAX = PT_FIXED + 17, + TPM_PT_PCR_COUNT = PT_FIXED + 18, + TPM_PT_PCR_SELECT_MIN = PT_FIXED + 19, + TPM_PT_CONTEXT_GAP_MAX = PT_FIXED + 20, + TPM_PT_NV_COUNTERS_MAX = PT_FIXED + 22, + TPM_PT_NV_INDEX_MAX = PT_FIXED + 23, + TPM_PT_MEMORY = PT_FIXED + 24, + TPM_PT_CLOCK_UPDATE = PT_FIXED + 25, + TPM_PT_CONTEXT_HASH = PT_FIXED + 26, + TPM_PT_CONTEXT_SYM = PT_FIXED + 27, + TPM_PT_CONTEXT_SYM_SIZE = PT_FIXED + 28, + TPM_PT_ORDERLY_COUNT = PT_FIXED + 29, + TPM_PT_MAX_COMMAND_SIZE = PT_FIXED + 30, + TPM_PT_MAX_RESPONSE_SIZE = PT_FIXED + 31, + TPM_PT_MAX_DIGEST = PT_FIXED + 32, + TPM_PT_MAX_OBJECT_CONTEXT = PT_FIXED + 33, + TPM_PT_MAX_SESSION_CONTEXT = PT_FIXED + 34, + TPM_PT_PS_FAMILY_INDICATOR = PT_FIXED + 35, + TPM_PT_PS_LEVEL = PT_FIXED + 36, + TPM_PT_PS_REVISION = PT_FIXED + 37, + TPM_PT_PS_DAY_OF_YEAR = PT_FIXED + 38, + TPM_PT_PS_YEAR = PT_FIXED + 39, + TPM_PT_SPLIT_MAX = PT_FIXED + 40, + TPM_PT_TOTAL_COMMANDS = PT_FIXED + 41, + TPM_PT_LIBRARY_COMMANDS = PT_FIXED + 42, + TPM_PT_VENDOR_COMMANDS = PT_FIXED + 43, + TPM_PT_NV_BUFFER_MAX = PT_FIXED + 44, + + PT_VAR = PT_GROUP * 2, + TPM_PT_PERMANENT = PT_VAR + 0, + TPM_PT_STARTUP_CLEAR = PT_VAR + 1, + TPM_PT_HR_NV_INDEX = PT_VAR + 2, + TPM_PT_HR_LOADED = PT_VAR + 3, + TPM_PT_HR_LOADED_AVAIL = PT_VAR + 4, + TPM_PT_HR_ACTIVE = PT_VAR + 5, + TPM_PT_HR_ACTIVE_AVAIL = PT_VAR + 6, + TPM_PT_HR_TRANSIENT_AVAIL = PT_VAR + 7, + TPM_PT_HR_PERSISTENT = PT_VAR + 8, + TPM_PT_HR_PERSISTENT_AVAIL = PT_VAR + 9, + TPM_PT_NV_COUNTERS = PT_VAR + 10, + TPM_PT_NV_COUNTERS_AVAIL = PT_VAR + 11, + TPM_PT_ALGORITHM_SET = PT_VAR + 12, + TPM_PT_LOADED_CURVES = PT_VAR + 13, + TPM_PT_LOCKOUT_COUNTER = PT_VAR + 14, + TPM_PT_MAX_AUTH_FAIL = PT_VAR + 15, + TPM_PT_LOCKOUT_INTERVAL = PT_VAR + 16, + TPM_PT_LOCKOUT_RECOVERY = PT_VAR + 17, + TPM_PT_NV_WRITE_RECOVERY = PT_VAR + 18, + TPM_PT_AUDIT_COUNTER_0 = PT_VAR + 19, + TPM_PT_AUDIT_COUNTER_1 = PT_VAR + 20, +} TPM_PT_T; +typedef UINT32 TPM_PT; + +/* PCR Property Tag */ +typedef enum { + TPM_PT_PCR_FIRST = 0x00000000, + TPM_PT_PCR_SAVE = TPM_PT_PCR_FIRST, + TPM_PT_PCR_EXTEND_L0 = 0x00000001, + TPM_PT_PCR_RESET_L0 = 0x00000002, + TPM_PT_PCR_EXTEND_L1 = 0x00000003, + TPM_PT_PCR_RESET_L1 = 0x00000004, + TPM_PT_PCR_EXTEND_L2 = 0x00000005, + TPM_PT_PCR_RESET_L2 = 0x00000006, + TPM_PT_PCR_EXTEND_L3 = 0x00000007, + TPM_PT_PCR_RESET_L3 = 0x00000008, + TPM_PT_PCR_EXTEND_L4 = 0x00000009, + TPM_PT_PCR_RESET_L4 = 0x0000000A, + TPM_PT_PCR_NO_INCREMENT = 0x00000011, + TPM_PT_PCR_DRTM_RESET = 0x00000012, + TPM_PT_PCR_POLICY = 0x00000013, + TPM_PT_PCR_AUTH = 0x00000014, + TPM_PT_PCR_LAST = TPM_PT_PCR_AUTH, +} TPM_PT_PCR_T; +typedef UINT32 TPM_PT_PCR; + +/* Platform Specific */ +typedef enum { + TPM_PS_MAIN = 0x00000000, + TPM_PS_PC = 0x00000001, + TPM_PS_PDA = 0x00000002, + TPM_PS_CELL_PHONE = 0x00000003, + TPM_PS_SERVER = 0x00000004, + TPM_PS_PERIPHERAL = 0x00000005, + TPM_PS_TSS = 0x00000006, + TPM_PS_STORAGE = 0x00000007, + TPM_PS_AUTHENTICATION = 0x00000008, + TPM_PS_EMBEDDED = 0x00000009, + TPM_PS_HARDCOPY = 0x0000000A, + TPM_PS_INFRASTRUCTURE = 0x0000000B, + TPM_PS_VIRTUALIZATION = 0x0000000C, + TPM_PS_TNC = 0x0000000D, + TPM_PS_MULTI_TENANT = 0x0000000E, + TPM_PS_TC = 0x0000000F, +} TPM_PS_T; +typedef UINT32 TPM_PS; + + +/* HANDLES */ +typedef UINT32 TPM_HANDLE; + +/* Handle Types */ +typedef enum { + TPM_HT_PCR = 0x00, + TPM_HT_NV_INDEX = 0x01, + TPM_HT_HMAC_SESSION = 0x02, + TPM_HT_LOADED_SESSION = 0x02, + TPM_HT_POLICY_SESSION = 0x03, + TPM_HT_ACTIVE_SESSION = 0x03, + TPM_HT_PERMANENT = 0x40, + TPM_HT_TRANSIENT = 0x80, + TPM_HT_PERSISTENT = 0x81, +} TPM_HT_T; +typedef UINT8 TPM_HT; + +/* Permanent Handles */ +typedef enum { + TPM_RH_FIRST = 0x40000000, + TPM_RH_SRK = TPM_RH_FIRST, + TPM_RH_OWNER = 0x40000001, + TPM_RH_REVOKE = 0x40000002, + TPM_RH_TRANSPORT = 0x40000003, + TPM_RH_OPERATOR = 0x40000004, + TPM_RH_ADMIN = 0x40000005, + TPM_RH_EK = 0x40000006, + TPM_RH_NULL = 0x40000007, + TPM_RH_UNASSIGNED = 0x40000008, + TPM_RS_PW = 0x40000009, + TPM_RH_LOCKOUT = 0x4000000A, + TPM_RH_ENDORSEMENT = 0x4000000B, + TPM_RH_PLATFORM = 0x4000000C, + TPM_RH_PLATFORM_NV = 0x4000000D, + TPM_RH_AUTH_00 = 0x40000010, + TPM_RH_AUTH_FF = 0x4000010F, + TPM_RH_LAST = TPM_RH_AUTH_FF, +} TPM_RH_T; +typedef UINT32 TPM_RH; + +/* Handle Value Constants */ +typedef enum { + HR_HANDLE_MASK = 0x00FFFFFF, + HR_RANGE_MASK = 0xFF000000, + HR_SHIFT = 24, + HR_PCR = (TPM_HT_PCR << HR_SHIFT), + HR_HMAC_SESSION = (TPM_HT_HMAC_SESSION << HR_SHIFT), + HR_POLICY_SESSION = (TPM_HT_POLICY_SESSION << HR_SHIFT), + HR_TRANSIENT = (TPM_HT_TRANSIENT << HR_SHIFT), + HR_PERSISTENT = (TPM_HT_PERSISTENT << HR_SHIFT), + HR_NV_INDEX = (TPM_HT_NV_INDEX << HR_SHIFT), + HR_PERMANENT = (TPM_HT_PERMANENT << HR_SHIFT), + PCR_FIRST = (HR_PCR + 0), + PCR_LAST = (PCR_FIRST + IMPLEMENTATION_PCR-1), + HMAC_SESSION_FIRST = (HR_HMAC_SESSION + 0), + HMAC_SESSION_LAST = (HMAC_SESSION_FIRST+MAX_ACTIVE_SESSIONS-1), + LOADED_SESSION_FIRST = HMAC_SESSION_FIRST, + LOADED_SESSION_LAST = HMAC_SESSION_LAST, + POLICY_SESSION_FIRST = (HR_POLICY_SESSION + 0), + POLICY_SESSION_LAST = (POLICY_SESSION_FIRST+MAX_ACTIVE_SESSIONS-1), + TRANSIENT_FIRST = (HR_TRANSIENT + 0), + ACTIVE_SESSION_FIRST = POLICY_SESSION_FIRST, + ACTIVE_SESSION_LAST = POLICY_SESSION_LAST, + TRANSIENT_LAST = (TRANSIENT_FIRST+MAX_LOADED_OBJECTS-1), + PERSISTENT_FIRST = (HR_PERSISTENT + 0), + PERSISTENT_LAST = (PERSISTENT_FIRST + 0x00FFFFFF), + PLATFORM_PERSISTENT = (PERSISTENT_FIRST + 0x00800000), + NV_INDEX_FIRST = (HR_NV_INDEX + 0), + NV_INDEX_LAST = (NV_INDEX_FIRST + 0x00FFFFFF), + PERMANENT_FIRST = TPM_RH_FIRST, + PERMANENT_LAST = TPM_RH_LAST, +} TPM_HC_T; +typedef UINT32 TPM_HC; + + +/* Attributes */ +typedef UINT32 TPMA_ALGORITHM; +enum TPMA_ALGORITHM_mask { + TPMA_ALGORITHM_asymmetric = 0x00000001, + TPMA_ALGORITHM_symmetric = 0x00000002, + TPMA_ALGORITHM_hash = 0x00000004, + TPMA_ALGORITHM_object = 0x00000008, + TPMA_ALGORITHM_signing = 0x00000010, + TPMA_ALGORITHM_encrypting = 0x00000020, + TPMA_ALGORITHM_method = 0x00000040, +}; + +typedef UINT32 TPMA_OBJECT; +enum TPMA_OBJECT_mask { + TPMA_OBJECT_fixedTPM = 0x00000002, + TPMA_OBJECT_stClear = 0x00000004, + TPMA_OBJECT_fixedParent = 0x00000010, + TPMA_OBJECT_sensitiveDataOrigin = 0x00000020, + TPMA_OBJECT_userWithAuth = 0x00000040, + TPMA_OBJECT_adminWithPolicy = 0x00000080, + TPMA_OBJECT_noDA = 0x00000400, + TPMA_OBJECT_encryptedDuplication= 0x00000800, + TPMA_OBJECT_restricted = 0x00008000, + TPMA_OBJECT_decrypt = 0x00010000, + TPMA_OBJECT_sign = 0x00020000, +}; + +typedef BYTE TPMA_SESSION; +enum TPMA_SESSION_mask { + TPMA_SESSION_continueSession = 0x01, + TPMA_SESSION_auditExclusive = 0x02, + TPMA_SESSION_auditReset = 0x04, + TPMA_SESSION_decrypt = 0x20, + TPMA_SESSION_encrypt = 0x40, + TPMA_SESSION_audit = 0x80, +}; + +typedef BYTE TPMA_LOCALITY; +enum TPMA_LOCALITY_mask { + TPM_LOC_ZERO = 0x01, + TPM_LOC_ONE = 0x02, + TPM_LOC_TWO = 0x04, + TPM_LOC_THREE = 0x08, + TPM_LOC_FOUR = 0x10, +}; + +typedef UINT32 TPMA_PERMANENT; +enum TPMA_PERMANENT_mask { + TPMA_PERMANENT_ownerAuthSet = 0x00000001, + TPMA_PERMANENT_endorsementAuthSet = 0x00000002, + TPMA_PERMANENT_lockoutAuthSet = 0x00000004, + TPMA_PERMANENT_disableClear = 0x00000100, + TPMA_PERMANENT_inLockout = 0x00000200, + TPMA_PERMANENT_tpmGeneratedEPS = 0x00000400, +}; + +typedef UINT32 TPMA_STARTUP_CLEAR; +enum TPMA_STARTUP_CLEAR_mask { + TPMA_STARTUP_CLEAR_phEnable = 0x00000001, + TPMA_STARTUP_CLEAR_shEnable = 0x00000002, + TPMA_STARTUP_CLEAR_ehEnable = 0x00000004, + TPMA_STARTUP_CLEAR_phEnableNV = 0x00000008, + TPMA_STARTUP_CLEAR_orderly = 0x80000000, +}; + +typedef UINT32 TPMA_MEMORY; +enum TPMA_MEMORY_mask { + TPMA_MEMORY_sharedRAM = 0x00000001, + TPMA_MEMORY_sharedNV = 0x00000002, + TPMA_MEMORY_objectCopiedToRam = 0x00000004, +}; + +typedef UINT32 TPMA_CC; +enum TPMA_CC_mask { + TPMA_CC_commandIndex = 0x0000FFFF, + TPMA_CC_nv = 0x00400000, + TPMA_CC_extensive = 0x00800000, + TPMA_CC_flushed = 0x01000000, + TPMA_CC_cHandles = 0x0E000000, + TPMA_CC_rHandle = 0x10000000, + TPMA_CC_V = 0x20000000, +}; + + + +/* Interface Types */ + +typedef BYTE TPMI_YES_NO; +typedef TPM_HANDLE TPMI_DH_OBJECT; +typedef TPM_HANDLE TPMI_DH_PARENT; +typedef TPM_HANDLE TPMI_DH_PERSISTENT; +typedef TPM_HANDLE TPMI_DH_ENTITY; +typedef TPM_HANDLE TPMI_DH_PCR; +typedef TPM_HANDLE TPMI_SH_AUTH_SESSION; +typedef TPM_HANDLE TPMI_SH_HMAC; +typedef TPM_HANDLE TPMI_SH_POLICY; +typedef TPM_HANDLE TPMI_DH_CONTEXT; +typedef TPM_HANDLE TPMI_RH_HIERARCHY; +typedef TPM_HANDLE TPMI_RH_ENABLES; +typedef TPM_HANDLE TPMI_RH_HIERARCHY_AUTH; +typedef TPM_HANDLE TPMI_RH_PLATFORM; +typedef TPM_HANDLE TPMI_RH_OWNER; +typedef TPM_HANDLE TPMI_RH_ENDORSEMENT; +typedef TPM_HANDLE TPMI_RH_PROVISION; +typedef TPM_HANDLE TPMI_RH_CLEAR; +typedef TPM_HANDLE TPMI_RH_NV_AUTH; +typedef TPM_HANDLE TPMI_RH_LOCKOUT; +typedef TPM_HANDLE TPMI_RH_NV_INDEX; + +typedef TPM_ALG_ID TPMI_ALG_HASH; +typedef TPM_ALG_ID TPMI_ALG_ASYM; +typedef TPM_ALG_ID TPMI_ALG_SYM; +typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT; +typedef TPM_ALG_ID TPMI_ALG_SYM_MODE; +typedef TPM_ALG_ID TPMI_ALG_KDF; +typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME; +typedef TPM_ALG_ID TPMI_ECC_KEY_EXCHANGE; + +typedef TPM_ST TPMI_ST_COMMAND_TAG; + + +/* Structures */ + +typedef struct TPMS_ALGORITHM_DESCRIPTION { + TPM_ALG_ID alg; + TPMA_ALGORITHM attributes; +} TPMS_ALGORITHM_DESCRIPTION; + + +typedef union TPMU_HA { +#ifdef WOLFSSL_SHA512 + BYTE sha512[WC_SHA512_DIGEST_SIZE]; +#endif +#ifdef WOLFSSL_SHA384 + BYTE sha384[WC_SHA384_DIGEST_SIZE]; +#endif +#ifndef NO_SHA256 + BYTE sha256[WC_SHA256_DIGEST_SIZE]; +#endif +#ifdef WOLFSSL_SHA224 + BYTE sha224[WC_SHA224_DIGEST_SIZE]; +#endif +#ifndef NO_SHA + BYTE sha[WC_SHA_DIGEST_SIZE]; +#endif +#ifndef NO_MD5 + BYTE md5[WC_MD5_DIGEST_SIZE]; +#endif + BYTE H[WC_MAX_DIGEST_SIZE]; +} TPMU_HA; + +typedef struct TPMT_HA { + TPMI_ALG_HASH hashAlg; + TPMU_HA digest; +} TPMT_HA; + +typedef struct TPM2B_DIGEST { + UINT16 size; + BYTE buffer[sizeof(TPMU_HA)]; +} TPM2B_DIGEST; + +typedef struct TPM2B_DATA { + UINT16 size; + BYTE buffer[sizeof(TPMT_HA)]; +} TPM2B_DATA; + +typedef TPM2B_DIGEST TPM2B_NONCE; +typedef TPM2B_DIGEST TPM2B_AUTH; +typedef TPM2B_DIGEST TPM2B_OPERAND; + +typedef struct TPM2B_EVENT { + UINT16 size; + BYTE buffer[1024]; +} TPM2B_EVENT; + +typedef struct TPM2B_MAX_BUFFER { + UINT16 size; + BYTE buffer[MAX_DIGEST_BUFFER]; +} TPM2B_MAX_BUFFER; + +typedef struct TPM2B_MAX_NV_BUFFER { + UINT16 size; + BYTE buffer[MAX_NV_BUFFER_SIZE]; +} TPM2B_MAX_NV_BUFFER; + + +typedef TPM2B_DIGEST TPM2B_TIMEOUT; + +typedef struct TPM2B_IV { + UINT16 size; + BYTE buffer[MAX_SYM_BLOCK_SIZE]; +} TPM2B_IV; + + +/* Names */ +typedef union TPMU_NAME { + TPMT_HA digest; + TPM_HANDLE handle; +} TPMU_NAME; + +typedef struct TPM2B_NAME { + UINT16 size; + BYTE name[sizeof(TPMU_NAME)]; +} TPM2B_NAME; + + +/* PCR */ + +typedef struct TPMS_PCR_SELECT { + BYTE sizeofSelect; + BYTE pcrSelect[PCR_SELECT_MIN]; +} TPMS_PCR_SELECT; + + +typedef struct TPMS_PCR_SELECTION { + TPMI_ALG_HASH hash; + BYTE sizeofSelect; + BYTE pcrSelect[PCR_SELECT_MIN]; +} TPMS_PCR_SELECTION; + + +/* Tickets */ + +typedef struct TPMT_TK_CREATION { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_CREATION; + +typedef struct TPMT_TK_VERIFIED { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_VERIFIED; + +typedef struct TPMT_TK_AUTH { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_AUTH; + +typedef struct TPMT_TK_HASHCHECK { + TPM_ST tag; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_DIGEST digest; +} TPMT_TK_HASHCHECK; + +typedef struct TPMS_ALG_PROPERTY { + TPM_ALG_ID alg; + TPMA_ALGORITHM algProperties; +} TPMS_ALG_PROPERTY; + +typedef struct TPMS_TAGGED_PROPERTY { + TPM_PT property; + UINT32 value; +} TPMS_TAGGED_PROPERTY; + +typedef struct TPMS_TAGGED_PCR_SELECT { + TPM_PT_PCR tag; + BYTE sizeofSelect; + BYTE pcrSelect[PCR_SELECT_MAX]; +} TPMS_TAGGED_PCR_SELECT; + +typedef struct TPMS_TAGGED_POLICY { + TPM_HANDLE handle; + TPMT_HA policyHash; +} TPMS_TAGGED_POLICY; + + +/* Lists */ + +typedef struct TPML_CC { + UINT32 count; + TPM_CC commandCodes[MAX_CAP_CC]; +} TPML_CC; + +typedef struct TPML_CCA { + UINT32 count; + TPMA_CC commandAttributes[MAX_CAP_CC]; +} TPML_CCA; + +typedef struct TPML_ALG { + UINT32 count; + TPM_ALG_ID algorithms[MAX_ALG_LIST_SIZE]; +} TPML_ALG; + +typedef struct TPML_HANDLE { + UINT32 count; + TPM_HANDLE handle[MAX_CAP_HANDLES]; +} TPML_HANDLE; + +typedef struct TPML_DIGEST { + UINT32 count; + TPM2B_DIGEST digests[8]; +} TPML_DIGEST; + +typedef struct TPML_DIGEST_VALUES { + UINT32 count; + TPMT_HA digests[HASH_COUNT]; +} TPML_DIGEST_VALUES; + +typedef struct TPML_PCR_SELECTION { + UINT32 count; + TPMS_PCR_SELECTION pcrSelections[HASH_COUNT]; +} TPML_PCR_SELECTION; + +typedef struct TPML_ALG_PROPERTY { + UINT32 count; + TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS]; +} TPML_ALG_PROPERTY; + +typedef struct TPML_TAGGED_TPM_PROPERTY { + UINT32 count; + TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES]; +} TPML_TAGGED_TPM_PROPERTY; + +typedef struct TPML_TAGGED_PCR_PROPERTY { + UINT32 count; + TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES]; +} TPML_TAGGED_PCR_PROPERTY; + +typedef struct TPML_ECC_CURVE { + UINT32 count; + TPM_ECC_CURVE eccCurves[MAX_ECC_CURVES]; +} TPML_ECC_CURVE; + +typedef struct TPML_TAGGED_POLICY { + UINT32 count; + TPMS_TAGGED_POLICY policies[MAX_TAGGED_POLICIES]; +} TPML_TAGGED_POLICY; + + +/* Capabilities Structures */ + +typedef union TPMU_CAPABILITIES { + TPML_ALG_PROPERTY algorithms; /* TPM_CAP_ALGS */ + TPML_HANDLE handles; /* TPM_CAP_HANDLES */ + TPML_CCA command; /* TPM_CAP_COMMANDS */ + TPML_CC ppCommands; /* TPM_CAP_PP_COMMANDS */ + TPML_CC auditCommands; /* TPM_CAP_AUDIT_COMMANDS */ + TPML_PCR_SELECTION assignedPCR; /* TPM_CAP_PCRS */ + TPML_TAGGED_TPM_PROPERTY tpmProperties; /* TPM_CAP_TPM_PROPERTIES */ + TPML_TAGGED_PCR_PROPERTY pcrProperties; /* TPM_CAP_PCR_PROPERTIES */ + TPML_ECC_CURVE eccCurves; /* TPM_CAP_ECC_CURVES */ + TPML_TAGGED_POLICY authPolicies; /* TPM_CAP_AUTH_POLICIES */ +} TPMU_CAPABILITIES; + +typedef struct TPMS_CAPABILITY_DATA { + TPM_CAP capability; + TPMU_CAPABILITIES data; +} TPMS_CAPABILITY_DATA; + +typedef struct TPMS_CLOCK_INFO { + UINT64 clock; + UINT32 resetCount; + UINT32 restartCount; + TPMI_YES_NO safe; +} TPMS_CLOCK_INFO; + +typedef struct TPMS_TIME_INFO { + UINT64 time; + TPMS_CLOCK_INFO clockInfo; +} TPMS_TIME_INFO; + +typedef struct TPMS_TIME_ATTEST_INFO { + TPMS_TIME_INFO time; + UINT64 firmwareVersion; +} TPMS_TIME_ATTEST_INFO; + +typedef struct TPMS_CERTIFY_INFO { + TPM2B_NAME name; + TPM2B_NAME qualifiedName; +} TPMS_CERTIFY_INFO; + +typedef struct TPMS_QUOTE_INFO { + TPML_PCR_SELECTION pcrSelect; + TPM2B_DIGEST pcrDigest; +} TPMS_QUOTE_INFO; + +typedef struct TPMS_COMMAND_AUDIT_INFO { + UINT64 auditCounter; + TPM_ALG_ID digestAlg; + TPM2B_DIGEST auditDigest; + TPM2B_DIGEST commandDigest; +} TPMS_COMMAND_AUDIT_INFO; + +typedef struct TPMS_SESSION_AUDIT_INFO { + TPMI_YES_NO exclusiveSession; + TPM2B_DIGEST sessionDigest; +} TPMS_SESSION_AUDIT_INFO; + +typedef struct TPMS_CREATION_INFO { + TPM2B_NAME objectName; + TPM2B_DIGEST creationHash; +} TPMS_CREATION_INFO; + +typedef struct TPMS_NV_CERTIFY_INFO { + TPM2B_NAME indexName; + UINT16 offset; + TPM2B_MAX_NV_BUFFER nvContents; +} TPMS_NV_CERTIFY_INFO; + + +typedef TPM_ST TPMI_ST_ATTEST; +typedef union TPMU_ATTEST { + TPMS_CERTIFY_INFO certify; /* TPM_ST_ATTEST_CERTIFY */ + TPMS_CREATION_INFO creation; /* TPM_ST_ATTEST_CREATION */ + TPMS_QUOTE_INFO quote; /* TPM_ST_ATTEST_QUOTE */ + TPMS_COMMAND_AUDIT_INFO commandAudit; /* TPM_ST_ATTEST_COMMAND_AUDIT */ + TPMS_SESSION_AUDIT_INFO sessionAudit; /* TPM_ST_ATTEST_SESSION_AUDIT */ + TPMS_TIME_ATTEST_INFO time; /* TPM_ST_ATTEST_TIME */ + TPMS_NV_CERTIFY_INFO nv; /* TPM_ST_ATTEST_NV */ +} TPMU_ATTEST; + +typedef struct TPMS_ATTEST { + TPM_GENERATED magic; + TPMI_ST_ATTEST type; + TPM2B_NAME qualifiedSigner; + TPM2B_DATA extraData; + TPMS_CLOCK_INFO clockInfo; + UINT64 firmwareVersion; + TPMU_ATTEST attested; +} TPMS_ATTEST; + +typedef struct TPM2B_ATTEST { + UINT16 size; + BYTE attestationData[sizeof(TPMS_ATTEST)]; +} TPM2B_ATTEST; + + +/* Authorization Structures */ + +typedef struct TPMS_AUTH_COMMAND { + TPMI_SH_AUTH_SESSION sessionHandle; + TPM2B_NONCE nonce; + TPMA_SESSION sessionAttributes; + TPM2B_AUTH hmac; +} TPMS_AUTH_COMMAND; + +typedef struct TPMS_AUTH_RESPONSE { + TPM2B_NONCE nonce; + TPMA_SESSION sessionAttributes; + TPM2B_AUTH hmac; +} TPMS_AUTH_RESPONSE; + + +/* Algorithm Parameters and Structures */ + +/* Symmetric */ +#ifndef NO_AES +typedef TPM_KEY_BITS TPMI_AES_KEY_BITS; +#endif + +typedef union TPMU_SYM_KEY_BITS { +#ifndef NO_AES + TPMI_AES_KEY_BITS aes; +#endif + TPM_KEY_BITS sym; +} TPMU_SYM_KEY_BITS; + +typedef union TPMU_SYM_MODE { +#ifndef NO_AES + TPMI_ALG_SYM_MODE aes; +#endif + TPMI_ALG_SYM_MODE sym; +} TPMU_SYM_MODE; + +typedef struct TPMT_SYM_DEF { + TPMI_ALG_SYM algorithm; + TPMU_SYM_KEY_BITS keyBits; + TPMU_SYM_MODE mode; + //TPMU_SYM_DETAILS details; +} TPMT_SYM_DEF; + +typedef struct TPMT_SYM_DEF_OBJECT { + TPMI_ALG_SYM_OBJECT algorithm; + TPMU_SYM_KEY_BITS keyBits; + TPMU_SYM_MODE mode; + //TPMU_SYM_DETAILS details; +} TPMT_SYM_DEF_OBJECT; + +typedef struct TPM2B_SYM_KEY { + UINT16 size; + BYTE buffer[MAX_SYM_KEY_BYTES]; +} TPM2B_SYM_KEY; + +typedef struct TPMS_SYMCIPHER_PARMS { + TPMT_SYM_DEF_OBJECT sym; +} TPMS_SYMCIPHER_PARMS; + +typedef struct TPM2B_LABEL { + UINT16 size; + BYTE buffer[LABEL_MAX_BUFFER]; +} TPM2B_LABEL; + +typedef struct TPMS_DERIVE { + TPM2B_LABEL label; + TPM2B_LABEL context; +} TPMS_DERIVE; + +typedef struct TPM2B_DERIVE { + UINT16 size; + BYTE buffer[sizeof(TPMS_DERIVE)]; +} TPM2B_DERIVE; + +typedef union TPMU_SENSITIVE_CREATE { + BYTE create[MAX_SYM_DATA]; + TPMS_DERIVE derive; +} TPMU_SENSITIVE_CREATE; + +typedef struct TPM2B_SENSITIVE_DATA { + UINT16 size; + BYTE buffer[sizeof(TPMU_SENSITIVE_CREATE)]; +} TPM2B_SENSITIVE_DATA; + +typedef struct TPMS_SENSITIVE_CREATE { + TPM2B_AUTH userAuth; + TPM2B_SENSITIVE_DATA data; +} TPMS_SENSITIVE_CREATE; + +typedef struct TPM2B_SENSITIVE_CREATE { + UINT16 size; + TPMS_SENSITIVE_CREATE sensitive; +} TPM2B_SENSITIVE_CREATE; + +typedef struct TPMS_SCHEME_HASH { + TPMI_ALG_HASH hashAlg; +} TPMS_SCHEME_HASH; + +typedef struct TPMS_SCHEME_ECDAA { + TPMI_ALG_HASH hashAlgo; + UINT16 count; +} TPMS_SCHEME_ECDAA; + +typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME; +typedef TPMS_SCHEME_HASH TPMS_SCHEME_HMAC; + +typedef union TPMU_SCHEME_KEYEDHASH { + TPMS_SCHEME_HMAC hmac; +} TPMU_SCHEME_KEYEDHASH; + +typedef struct TPMT_KEYEDHASH_SCHEME { + TPMI_ALG_KEYEDHASH_SCHEME scheme; + TPMU_SCHEME_KEYEDHASH details; +} TPMT_KEYEDHASH_SCHEME; + + +/* Asymmetric */ + +typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSASSA; +typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSAPSS; +typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECDSA; + +typedef TPMS_SCHEME_ECDAA TPMS_SIG_SCHEME_ECDAA; + + +typedef union TPMU_SIG_SCHEME { + TPMS_SIG_SCHEME_RSASSA rsassa; + TPMS_SIG_SCHEME_RSAPSS rsapss; + TPMS_SIG_SCHEME_ECDSA ecdsa; + TPMS_SIG_SCHEME_ECDAA ecdaa; + TPMS_SCHEME_HMAC hmac; + TPMS_SCHEME_HASH any; +} TPMU_SIG_SCHEME; + +typedef struct TPMT_SIG_SCHEME { + TPMI_ALG_SIG_SCHEME scheme; + TPMU_SIG_SCHEME details; +} TPMT_SIG_SCHEME; + + +/* Encryption / Key Exchange Schemes */ +typedef TPMS_SCHEME_HASH TPMS_ENC_SCHEME_OAEP; +typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECDH; +typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECMQV; + +/* Key Derivation Schemes */ +typedef TPMS_SCHEME_HASH TPMS_SCHEME_MGF1; +typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_56A; +typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF2; +typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_108; + +typedef union TPMU_KDF_SCHEME { + TPMS_SCHEME_MGF1 mgf1; + TPMS_SCHEME_KDF1_SP800_56A kdf1_sp800_56a; + TPMS_SCHEME_KDF2 kdf2; + TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108; + TPMS_SCHEME_HASH any; +} TPMU_KDF_SCHEME; + +typedef struct TPMT_KDF_SCHEME { + TPMI_ALG_KDF scheme; + TPMU_KDF_SCHEME details; +} TPMT_KDF_SCHEME; + +typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME; +typedef union TPMU_ASYM_SCHEME { + TPMS_KEY_SCHEME_ECDH ecdh; + TPMS_SIG_SCHEME_RSASSA rsassa; + TPMS_SIG_SCHEME_RSAPSS rsapss; + TPMS_SIG_SCHEME_ECDSA ecdsa; + TPMS_ENC_SCHEME_OAEP oaep; + TPMS_SCHEME_HASH anySig; +} TPMU_ASYM_SCHEME; + +typedef struct TPMT_ASYM_SCHEME { + TPMI_ALG_ASYM_SCHEME scheme; + TPMU_ASYM_SCHEME details; +} TPMT_ASYM_SCHEME; + +/* RSA */ +typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME; +typedef struct TPMT_RSA_SCHEME { + TPMI_ALG_RSA_SCHEME scheme; + TPMU_ASYM_SCHEME details; +} TPMT_RSA_SCHEME; + +typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT; +typedef struct TPMT_RSA_DECRYPT { + TPMI_ALG_RSA_DECRYPT scheme; + TPMU_ASYM_SCHEME details; +} TPMT_RSA_DECRYPT; + +typedef struct TPM2B_PUBLIC_KEY_RSA { + UINT16 size; + BYTE buffer[MAX_RSA_KEY_BYTES]; +} TPM2B_PUBLIC_KEY_RSA; + +typedef TPM_KEY_BITS TPMI_RSA_KEY_BITS; +typedef struct TPM2B_PRIVATE_KEY_RSA { + UINT16 size; + BYTE buffer[MAX_RSA_KEY_BYTES/2]; +} TPM2B_PRIVATE_KEY_RSA; + + +/* ECC */ +typedef struct TPM2B_ECC_PARAMETER { + UINT16 size; + BYTE buffer[MAX_ECC_KEY_BYTES]; +} TPM2B_ECC_PARAMETER; + +typedef struct TPMS_ECC_POINT { + TPM2B_ECC_PARAMETER x; + TPM2B_ECC_PARAMETER y; +} TPMS_ECC_POINT; + +typedef struct TPM2B_ECC_POINT { + UINT16 size; + TPMS_ECC_POINT point; +} TPM2B_ECC_POINT; + + +typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME; +typedef TPM_ECC_CURVE TPMI_ECC_CURVE; +typedef TPMT_SIG_SCHEME TPMT_ECC_SCHEME; + +typedef struct TPMS_ALGORITHM_DETAIL_ECC { + TPM_ECC_CURVE curveID; + UINT16 keySize; + TPMT_KDF_SCHEME kdf; + TPMT_ECC_SCHEME sign; + TPM2B_ECC_PARAMETER p; + TPM2B_ECC_PARAMETER a; + TPM2B_ECC_PARAMETER b; + TPM2B_ECC_PARAMETER gX; + TPM2B_ECC_PARAMETER gY; + TPM2B_ECC_PARAMETER n; + TPM2B_ECC_PARAMETER h; +} TPMS_ALGORITHM_DETAIL_ECC; + + +/* Signatures */ + +typedef struct TPMS_SIGNATURE_RSA { + TPMI_ALG_HASH hash; + TPM2B_PUBLIC_KEY_RSA sig; +} TPMS_SIGNATURE_RSA; + +typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSASSA; +typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSAPSS; + +typedef struct TPMS_SIGNATURE_ECC { + TPMI_ALG_HASH hash; + TPM2B_ECC_PARAMETER signatureR; + TPM2B_ECC_PARAMETER signatureS; +} TPMS_SIGNATURE_ECC; + +typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDSA; +typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDAA; + +typedef union TPMU_SIGNATURE { + TPMS_SIGNATURE_ECDSA ecdsa; + TPMS_SIGNATURE_ECDAA ecdaa; + TPMT_HA hmac; + TPMS_SCHEME_HASH any; +} TPMU_SIGNATURE; + +typedef struct TPMT_SIGNATURE { + TPMI_ALG_SIG_SCHEME sigAlgo; + TPMU_SIGNATURE signature; +} TPMT_SIGNATURE; + + +/* Key/Secret Exchange */ + +typedef union TPMU_ENCRYPTED_SECRET { + BYTE ecc[sizeof(TPMS_ECC_POINT)]; /* TPM_ALG_ECC */ + BYTE rsa[MAX_RSA_KEY_BYTES]; /* TPM_ALG_RSA */ + BYTE symmetric[sizeof(TPM2B_DIGEST)]; /* TPM_ALG_SYMCIPHER */ + BYTE keyedHash[sizeof(TPM2B_DIGEST)]; /* TPM_ALG_KEYEDHASH */ +} TPMU_ENCRYPTED_SECRET; + +typedef struct TPM2B_ENCRYPTED_SECRET { + UINT16 size; + BYTE secret[sizeof(TPMU_ENCRYPTED_SECRET)]; +} TPM2B_ENCRYPTED_SECRET; + + +/* Key/Object Complex */ + +typedef TPM_ALG_ID TPMI_ALG_PUBLIC; + +typedef union TPMU_PUBLIC_ID { + TPM2B_DIGEST keyedHash; /* TPM_ALG_KEYEDHASH */ + TPM2B_DIGEST sym; /* TPM_ALG_SYMCIPHER */ + TPM2B_PUBLIC_KEY_RSA rsa; /* TPM_ALG_RSA */ + TPMS_ECC_POINT ecc; /* TPM_ALG_ECC */ + TPMS_DERIVE derive; +} TPMU_PUBLIC_ID; + +typedef struct TPMS_KEYEDHASH_PARMS { + TPMT_KEYEDHASH_SCHEME scheme; +} TPMS_KEYEDHASH_PARMS; + + +typedef struct TPMS_ASYM_PARMS { + TPMT_SYM_DEF_OBJECT symmetric; + TPMT_ASYM_SCHEME scheme; +} TPMS_ASYM_PARMS; + +typedef struct TPMS_RSA_PARMS { + TPMT_SYM_DEF_OBJECT symmetric; + TPMT_RSA_SCHEME scheme; + TPMI_RSA_KEY_BITS keyBits; + UINT32 exponent; +} TPMS_RSA_PARMS; + +typedef struct TPMS_ECC_PARMS { + TPMT_SYM_DEF_OBJECT symmetric; + TPMT_ECC_SCHEME scheme; + TPMI_ECC_CURVE curveID; + TPMT_KDF_SCHEME kdf; +} TPMS_ECC_PARMS; + +typedef union TPMU_PUBLIC_PARMS { + TPMS_KEYEDHASH_PARMS keyedHashDetail; + TPMS_SYMCIPHER_PARMS symDetail; + TPMS_RSA_PARMS rsaDetail; + TPMS_ECC_PARMS eccDetail; + TPMS_ASYM_PARMS asymDetail; +} TPMU_PUBLIC_PARMS; + +typedef struct TPMT_PUBLIC_PARMS { + TPMI_ALG_PUBLIC type; + TPMU_PUBLIC_PARMS parameters; +} TPMT_PUBLIC_PARMS; + + +typedef struct TPMT_PUBLIC { + TPMI_ALG_PUBLIC type; + TPMI_ALG_HASH nameAlg; + TPMA_OBJECT objectAttributes; + TPM2B_DIGEST authPolicy; + TPMU_PUBLIC_PARMS parameters; + TPMU_PUBLIC_ID unique; +} TPMT_PUBLIC; + +typedef struct TPM2B_PUBLIC { + UINT16 size; + TPMT_PUBLIC publicArea; +} TPM2B_PUBLIC; + +typedef struct TPM2B_TEMPLATE { + UINT16 size; + BYTE buffer[sizeof(TPMT_PUBLIC)]; +} TPM2B_TEMPLATE; + + +/* Private Structures */ + +typedef struct TPM2B_PRIVATE_VENDOR_SPECIFIC { + UINT16 size; + BYTE buffer[PRIVATE_VENDOR_SPECIFIC_BYTES]; +} TPM2B_PRIVATE_VENDOR_SPECIFIC; + +typedef union TPMU_SENSITIVE_COMPOSITE { + TPM2B_PRIVATE_KEY_RSA rsa; /* TPM_ALG_RSA */ + TPM2B_ECC_PARAMETER ecc; /* TPM_ALG_ECC */ + TPM2B_SENSITIVE_DATA bits; /* TPM_ALG_KEYEDHASH */ + TPM2B_SYM_KEY sym; /* TPM_ALG_SYMCIPHER */ + TPM2B_PRIVATE_VENDOR_SPECIFIC any; +} TPMU_SENSITIVE_COMPOSITE; + + +typedef struct TPMT_SENSITIVE { + TPMI_ALG_PUBLIC sensitiveType; + TPM2B_AUTH authValue; + TPM2B_DIGEST seedValue; + TPMU_SENSITIVE_COMPOSITE sensitive; +} TPMT_SENSITIVE; + +typedef struct TPM2B_SENSITIVE { + UINT16 size; + TPMT_SENSITIVE sensitiveArea; +} TPM2B_SENSITIVE; + + +typedef struct TPMT_PRIVATE { + TPM2B_DIGEST integrityOuter; + TPM2B_DIGEST integrityInner; + TPM2B_SENSITIVE sensitive; +} TPMT_PRIVATE; + +typedef struct TPM2B_PRIVATE { + UINT16 size; + BYTE buffer[sizeof(TPMT_PRIVATE)]; +} TPM2B_PRIVATE; + + +/* Identity Object */ + +typedef struct TPMS_ID_OBJECT { + TPM2B_DIGEST integrityHMAC; + TPM2B_DIGEST encIdentity; +} TPMS_ID_OBJECT; + +typedef struct TPM2B_ID_OBJECT { + UINT16 size; + BYTE buffer[sizeof(TPMS_ID_OBJECT)]; +} TPM2B_ID_OBJECT; + + +/* NV Storage Structures */ + +typedef UINT32 TPM_NV_INDEX; +enum TPM_NV_INDEX_mask { + TPM_NV_INDEX_index = 0x00FFFFFF, + TPM_NV_INDEX_RH_NV = 0xFF000000, +}; + +typedef enum TPM_NT { + TPM_NT_ORDINARY = 0x0, + TPM_NT_COUNTER = 0x1, + TPM_NT_BITS = 0x2, + TPM_NT_EXTEND = 0x4, + TPM_NT_PIN_FAIL = 0x8, + TPM_NT_PIN_PASS = 0x9, +} TPM_NT; + + +typedef struct TPMS_NV_PIN_COUNTER_PARAMETERS { + UINT32 pinCount; + UINT32 pinLimit; +} TPMS_NV_PIN_COUNTER_PARAMETERS; + +typedef UINT32 TPMA_NV; +enum TPMA_NV_mask { + TPMA_NV_PPWRITE = 0x00000001, + TPMA_NV_OWNERWRITE = 0x00000002, + TPMA_NV_AUTHWRITE = 0x00000004, + TPMA_NV_POLICYWRITE = 0x00000008, + TPMA_NV_TPM_NT = 0x000000F0, + TPMA_NV_POLICY_DELETE = 0x00000400, + TPMA_NV_WRITELOCKED = 0x00000800, + TPMA_NV_WRITEALL = 0x00001000, + TPMA_NV_WRITEDEFINE = 0x00002000, + TPMA_NV_WRITE_STCLEAR = 0x00004000, + TPMA_NV_GLOBALLOCK = 0x00008000, + TPMA_NV_PPREAD = 0x00010000, + TPMA_NV_OWNERREAD = 0x00020000, + TPMA_NV_AUTHREAD = 0x00040000, + TPMA_NV_POLICYREAD = 0x00080000, + TPMA_NV_NO_DA = 0x02000000, + TPMA_NV_ORDERLY = 0x04000000, + TPMA_NV_CLEAR_STCLEAR = 0x08000000, + TPMA_NV_READLOCKED = 0x10000000, + TPMA_NV_WRITTEN = 0x20000000, + TPMA_NV_PLATFORMCREATE = 0x40000000, + TPMA_NV_READ_STCLEAR = 0x80000000, +}; + +typedef struct TPMS_NV_PUBLIC { + TPMI_RH_NV_INDEX nvIndex; + TPMI_ALG_HASH nameAlg; + TPMA_NV attributes; + TPM2B_DIGEST authPolicy; + UINT16 dataSize; +} TPMS_NV_PUBLIC; + +typedef struct TPM2B_NV_PUBLIC { + UINT16 size; + TPMS_NV_PUBLIC nvPublic; +} TPM2B_NV_PUBLIC; + + +/* Context Data */ + +typedef struct TPM2B_CONTEXT_SENSITIVE { + UINT16 size; + BYTE buffer[MAX_CONTEXT_SIZE]; +} TPM2B_CONTEXT_SENSITIVE; + +typedef struct TPMS_CONTEXT_DATA { + TPM2B_DIGEST integrity; + TPM2B_CONTEXT_SENSITIVE encrypted; +} TPMS_CONTEXT_DATA; + +typedef struct TPM2B_CONTEXT_DATA { + UINT16 size; + BYTE buffer[sizeof(TPMS_CONTEXT_DATA)]; +} TPM2B_CONTEXT_DATA; + +typedef struct TPMS_CONTEXT { + UINT64 sequence; + TPMI_DH_CONTEXT savedHandle; + TPMI_RH_HIERARCHY hierarchy; + TPM2B_CONTEXT_DATA contextBlob; +} TPMS_CONTEXT; + + +typedef struct TPMS_CREATION_DATA { + TPML_PCR_SELECTION pcrSelect; + TPM2B_DIGEST pcrDigest; + TPMA_LOCALITY locality; + TPM_ALG_ID parentNameAlg; + TPM2B_NAME parentName; + TPM2B_NAME parentQualifiedName; + TPM2B_DATA outsideInfo; +} TPMS_CREATION_DATA; + +typedef struct TPM2B_CREATION_DATA { + UINT16 size; + TPMS_CREATION_DATA creationData; +} TPM2B_CREATION_DATA; + + +/* HAL IO Callbacks */ +struct TPM2_CTX; + +typedef TPM_RC (*TPM2HalIoCb)(struct TPM2_CTX*, const BYTE*, BYTE*, UINT16 size, + void* userCtx); + +typedef struct TPM2_CTX { + TPM2HalIoCb ioCb; + void* userCtx; +#ifndef SINGLE_THREADED + wolfSSL_Mutex hwLock; +#endif + + /* TPM TIS Info */ + int locality; + word32 caps; + word32 did_vid; + byte rid; + + /* Command Buffer */ + byte cmdBuf[MAX_COMMAND_SIZE]; +} TPM2_CTX; + + +/* Functions */ + +#define _TPM_Init TPM2_Init +WOLFSSL_API TPM_RC TPM2_Init(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx); + +typedef struct { + TPM_SU startupType; +} Startup_In; +WOLFSSL_API TPM_RC TPM2_Startup(Startup_In* in); + +typedef struct { + TPM_SU shutdownType; +} Shutdown_In; +WOLFSSL_API TPM_RC TPM2_Shutdown(Shutdown_In* in); + + +typedef struct { + TPM_CAP capability; + UINT32 property; + UINT32 propertyCount; +} GetCapability_In; +typedef struct { + TPMI_YES_NO moreData; + TPMS_CAPABILITY_DATA capabilityData; +} GetCapability_Out; +WOLFSSL_API TPM_RC TPM2_GetCapability(GetCapability_In* in, + GetCapability_Out* out); + + +typedef struct { + TPMI_YES_NO fullTest; +} SelfTest_In; +WOLFSSL_API TPM_RC TPM2_SelfTest(SelfTest_In* in); + +typedef struct { + TPML_ALG toTest; +} IncrementalSelfTest_In; +typedef struct { + TPML_ALG toDoList; +} IncrementalSelfTest_Out; +WOLFSSL_API TPM_RC TPM2_IncrementalSelfTest(IncrementalSelfTest_In* in, + IncrementalSelfTest_Out* out); + +typedef struct { + TPM2B_MAX_BUFFER outData; + TPM_RC testResult; +} GetTestResult_Out; +WOLFSSL_API TPM_RC TPM2_GetTestResult(GetTestResult_Out* out); + + +typedef struct { + UINT16 bytesRequested; +} GetRandom_In; +typedef struct { + TPM2B_DIGEST randomBytes; +} GetRandom_Out; +WOLFSSL_API TPM_RC TPM2_GetRandom(GetRandom_In* in, GetRandom_Out* out); + +typedef struct { + TPM2B_SENSITIVE_DATA inData; +} StirRandom_In; +WOLFSSL_API TPM_RC TPM2_StirRandom(StirRandom_In* in); + +typedef struct { + TPML_PCR_SELECTION pcrSelectionIn; +} PCR_Read_In; +typedef struct { + UINT32 pcrUpdateCounter; + TPML_PCR_SELECTION pcrSelectionOut; + TPML_DIGEST pcrValues; +} PCR_Read_Out; +WOLFSSL_API TPM_RC TPM2_PCR_Read(PCR_Read_In* in, PCR_Read_Out* out); + + +typedef struct { + TPMI_DH_PCR pcrHandle; + TPMS_AUTH_COMMAND auth; + TPML_DIGEST_VALUES digests; +} PCR_Extend_In; +WOLFSSL_API TPM_RC TPM2_PCR_Extend(PCR_Extend_In* in); + + +typedef struct { + TPMI_DH_OBJECT parentHandle; + TPMS_AUTH_COMMAND auth; + TPM2B_SENSITIVE_CREATE inSensitive; + TPM2B_PUBLIC inPublic; + TPM2B_DATA outsideInfo; + TPML_PCR_SELECTION creationPCR; +} Create_In; +typedef struct { + TPM2B_PRIVATE outPrivate; + TPM2B_PUBLIC outPublic; + TPM2B_CREATION_DATA creationData; + TPM2B_DIGEST creationHash; + TPMT_TK_CREATION creationTicket; +} Create_Out; +WOLFSSL_API TPM_RC TPM2_Create(Create_In* in, Create_Out* out); + +typedef struct { + TPMI_DH_OBJECT parentHandle; + TPMS_AUTH_COMMAND auth; + TPM2B_SENSITIVE_CREATE inSensitive; + TPM2B_PUBLIC inPublic; +} CreateLoaded_In; +typedef struct { + TPM_HANDLE objectHandle; + TPM2B_PRIVATE outPrivate; + TPM2B_PUBLIC outPublic; + TPM2B_NAME name; +} CreateLoaded_Out; +WOLFSSL_API TPM_RC TPM2_CreateLoaded(CreateLoaded_In* in, + CreateLoaded_Out* out); + + +typedef struct { + TPMI_RH_HIERARCHY primaryHandle; + TPM2B_SENSITIVE_CREATE inSensitive; + TPM2B_PUBLIC inPublic; + TPM2B_DATA outsideInfo; + TPML_PCR_SELECTION creationPCR; +} CreatePrimary_In; +typedef struct { + TPM_HANDLE objectHandle; + TPM2B_PUBLIC outPublic; + TPM2B_CREATION_DATA creationData; + TPM2B_DIGEST creationHash; + TPMT_TK_CREATION creationTicket; + TPM2B_NAME name; +} CreatePrimary_Out; +WOLFSSL_API TPM_RC TPM2_CreatePrimary(CreatePrimary_In* in, + CreatePrimary_Out* out); + +typedef struct { + TPMI_DH_OBJECT parentHandle; + TPMS_AUTH_COMMAND auth; + TPM2B_PRIVATE inPrivate; + TPM2B_PUBLIC inPublic; +} Load_In; +typedef struct { + TPM_HANDLE objectHandle; + TPM2B_NAME name; +} Load_Out; +WOLFSSL_API TPM_RC TPM2_Load(Load_In* in, Load_Out* out); + + +typedef struct { + TPMI_DH_CONTEXT flushHandle; +} FlushContext_In; +WOLFSSL_API TPM_RC TPM2_FlushContext(FlushContext_In* in); + + +typedef struct { + TPMI_DH_OBJECT itemHandle; + TPMS_AUTH_COMMAND auth; +} Unseal_In; +typedef struct { + TPM2B_SENSITIVE_DATA outData; +} Unseal_Out; +WOLFSSL_API TPM_RC TPM2_Unseal(Unseal_In* in, Unseal_Out* out); + + +typedef struct { + TPMI_DH_OBJECT tpmKey; + TPMI_DH_ENTITY bind; + TPM2B_NONCE nonceCaller; + TPM2B_ENCRYPTED_SECRET encryptedSalt; + TPM_SE sessionType; + TPMT_SYM_DEF symmetric; + TPMI_ALG_HASH authHash; +} StartAuthSession_In; +typedef struct { + TPMI_SH_AUTH_SESSION sessionHandle; + TPM2B_NONCE nonceTPM; +} StartAuthSession_Out; +WOLFSSL_API TPM_RC TPM2_StartAuthSession(StartAuthSession_In* in, + StartAuthSession_Out* out); + +typedef struct { + TPMI_SH_POLICY sessionHandle; +} PolicyRestart_In; +WOLFSSL_API TPM_RC TPM2_PolicyRestart(PolicyRestart_In* in); + + +typedef struct { + TPM2B_SENSITIVE inPrivate; + TPM2B_PUBLIC inPublic; + TPMI_RH_HIERARCHY hierarchy; +} LoadExternal_In; +typedef struct { + TPM_HANDLE objectHandle; + TPM2B_NAME name; +} LoadExternal_Out; +WOLFSSL_API TPM_RC TPM2_LoadExternal(LoadExternal_In* in, + LoadExternal_Out* out); + +typedef struct { + TPMI_DH_OBJECT objectHandle; +} ReadPublic_In; +typedef struct { + TPM2B_PUBLIC outPublic; + TPM2B_NAME name; + TPM2B_NAME qualifiedName; +} ReadPublic_Out; +WOLFSSL_API TPM_RC TPM2_ReadPublic(ReadPublic_In* in, ReadPublic_Out* out); + +typedef struct { + TPMI_DH_OBJECT activateHandle; + TPMI_DH_OBJECT keyHandle; + TPM2B_ID_OBJECT credentialBlob; + TPM2B_ENCRYPTED_SECRET secret; +} ActivateCredential_In; +typedef struct { + TPM2B_DIGEST certInfo; +} ActivateCredential_Out; +WOLFSSL_API TPM_RC TPM2_ActivateCredential(ActivateCredential_In* in, + ActivateCredential_Out* out); + +typedef struct { + TPMI_DH_OBJECT handle; + TPM2B_DIGEST credential; + TPM2B_NAME objectName; +} MakeCredential_In; +typedef struct { + TPM2B_ID_OBJECT credentialBlob; + TPM2B_ENCRYPTED_SECRET secret; +} MakeCredential_Out; +WOLFSSL_API TPM_RC TPM2_MakeCredential(MakeCredential_In* in, + MakeCredential_Out* out); + +typedef struct { + TPMI_DH_OBJECT objectHandle; + TPMI_DH_OBJECT parentHandle; + TPM2B_AUTH newAuth; +} ObjectChangeAuth_In; +typedef struct { + TPM2B_PRIVATE outPrivate; +} ObjectChangeAuth_Out; +WOLFSSL_API TPM_RC TPM2_ObjectChangeAuth(ObjectChangeAuth_In* in, + ObjectChangeAuth_Out* out); + + +typedef struct { + TPMI_DH_OBJECT objectHandle; + TPMI_DH_OBJECT newParentHandle; + TPM2B_DATA encryptionKeyIn; + TPMT_SYM_DEF_OBJECT symmetricAlg; +} Duplicate_In; +typedef struct { + TPM2B_DATA encryptionKeyOut; + TPM2B_PRIVATE duplicate; + TPM2B_ENCRYPTED_SECRET outSymSeed; +} Duplicate_Out; +WOLFSSL_API TPM_RC TPM2_Duplicate(Duplicate_In* in, Duplicate_Out* out); + +typedef struct { + TPMI_DH_OBJECT oldParent; + TPMI_DH_OBJECT newParent; + TPM2B_PRIVATE inDuplicate; + TPM2B_NAME name; + TPM2B_ENCRYPTED_SECRET inSymSeed; +} Rewrap_In; +typedef struct { + TPM2B_PRIVATE outDuplicate; + TPM2B_ENCRYPTED_SECRET outSymSeed; +} Rewrap_Out; +WOLFSSL_API TPM_RC TPM2_Rewrap(Rewrap_In* in, Rewrap_Out* out); + +typedef struct { + TPMI_DH_OBJECT parentHandle; + TPM2B_DATA encryptionKey; + TPM2B_PUBLIC objectPublic; + TPM2B_PRIVATE duplicate; + TPM2B_ENCRYPTED_SECRET inSymSeed; + TPMT_SYM_DEF_OBJECT symmetricAlg; +} Import_In; +typedef struct { + TPM2B_PRIVATE outPrivate; +} Import_Out; +WOLFSSL_API TPM_RC TPM2_Import(Import_In* in, Import_Out* out); + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPM2B_PUBLIC_KEY_RSA message; + TPMT_RSA_DECRYPT inScheme; + TPM2B_DATA label; +} RSA_Encrypt_In; +typedef struct { + TPM2B_PUBLIC_KEY_RSA outData; +} RSA_Encrypt_Out; +WOLFSSL_API TPM_RC TPM2_RSA_Encrypt(RSA_Encrypt_In* in, RSA_Encrypt_Out* out); + + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPM2B_PUBLIC_KEY_RSA cipherText; + TPMT_RSA_DECRYPT inScheme; + TPM2B_DATA label; +} RSA_Decrypt_In; +typedef struct { + TPM2B_PUBLIC_KEY_RSA message; +} RSA_Decrypt_Out; +WOLFSSL_API TPM_RC TPM2_RSA_Decrypt(RSA_Decrypt_In* in, RSA_Decrypt_Out* out); + + +typedef struct { + TPMI_DH_OBJECT keyHandle; +} ECDH_KeyGen_In; +typedef struct { + TPM2B_ECC_POINT zPoint; + TPM2B_ECC_POINT pubPoint; +} ECDH_KeyGen_Out; +WOLFSSL_API TPM_RC TPM2_ECDH_KeyGen(ECDH_KeyGen_In* in, ECDH_KeyGen_Out* out); + + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPM2B_ECC_POINT inPoint; +} ECDH_ZGen_In; +typedef struct { + TPM2B_ECC_POINT outPoint; +} ECDH_ZGen_Out; +WOLFSSL_API TPM_RC TPM2_ECDH_ZGen(ECDH_ZGen_In* in, ECDH_ZGen_Out* out); + +typedef struct { + TPMI_ECC_CURVE curveID; +} ECC_Parameters_In; +typedef struct { + TPMS_ALGORITHM_DETAIL_ECC parameters; +} ECC_Parameters_Out; +WOLFSSL_API TPM_RC TPM2_ECC_Parameters(ECC_Parameters_In* in, + ECC_Parameters_Out* out); + +typedef struct { + TPMI_DH_OBJECT keyA; + TPM2B_ECC_POINT inQsB; + TPM2B_ECC_POINT inQeB; + TPMI_ECC_KEY_EXCHANGE inScheme; + UINT16 counter; +} ZGen_2Phase_In; +typedef struct { + TPM2B_ECC_POINT outZ1; + TPM2B_ECC_POINT outZ2; +} ZGen_2Phase_Out; +WOLFSSL_API TPM_RC TPM2_ZGen_2Phase(ZGen_2Phase_In* in, ZGen_2Phase_Out* out); + + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPMI_YES_NO decrypt; + TPMI_ALG_SYM_MODE mode; + TPM2B_IV ivIn; + TPM2B_MAX_BUFFER inData; +} EncryptDecrypt_In; +typedef struct { + TPM2B_MAX_BUFFER outData; + TPM2B_IV ivOut; +} EncryptDecrypt_Out; +WOLFSSL_API TPM_RC TPM2_EncryptDecrypt(EncryptDecrypt_In* in, + EncryptDecrypt_Out* out); + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPM2B_MAX_BUFFER inData; + TPMI_YES_NO decrypt; + TPMI_ALG_SYM_MODE mode; + TPM2B_IV ivIn; +} EncryptDecrypt2_In; +typedef struct { + TPM2B_MAX_BUFFER outData; + TPM2B_IV ivOut; +} EncryptDecrypt2_Out; +WOLFSSL_API TPM_RC TPM2_EncryptDecrypt2(EncryptDecrypt2_In* in, + EncryptDecrypt2_Out* out); + + +typedef struct { + TPM2B_MAX_BUFFER data; + TPMI_ALG_HASH hashAlg; + TPMI_RH_HIERARCHY hierarchy; +} Hash_In; +typedef struct { + TPM2B_DIGEST outHash; + TPMT_TK_HASHCHECK validation; +} Hash_Out; +WOLFSSL_API TPM_RC TPM2_Hash(Hash_In* in, Hash_Out* out); + +typedef struct { + TPMI_DH_OBJECT handle; + TPM2B_MAX_BUFFER buffer; + TPMI_ALG_HASH hashAlg; +} HMAC_In; +typedef struct { + TPM2B_DIGEST outHMAC; +} HMAC_Out; +WOLFSSL_API TPM_RC TPM2_HMAC(HMAC_In* in, HMAC_Out* out); + + +typedef struct { + TPMI_DH_OBJECT handle; + TPM2B_AUTH auth; + TPMI_ALG_HASH hashAlg; +} HMAC_Start_In; +typedef struct { + TPMI_DH_OBJECT sequenceHandle; +} HMAC_Start_Out; +WOLFSSL_API TPM_RC TPM2_HMAC_Start(HMAC_Start_In* in, HMAC_Start_Out* out); + + +typedef struct { + TPM2B_AUTH auth; + TPMI_ALG_HASH hashAlg; +} HashSequenceStart_In; +typedef struct { + TPMI_DH_OBJECT sequenceHandle; +} HashSequenceStart_Out; +WOLFSSL_API TPM_RC TPM2_HashSequenceStart(HashSequenceStart_In* in, + HashSequenceStart_Out* out); + +typedef struct { + TPMI_DH_OBJECT sequenceHandle; + TPM2B_MAX_BUFFER buffer; +} SequenceUpdate_In; +WOLFSSL_API TPM_RC TPM2_SequenceUpdate(SequenceUpdate_In* in); + +typedef struct { + TPMI_DH_OBJECT sequenceHandle; + TPM2B_MAX_BUFFER buffer; + TPMI_RH_HIERARCHY hierarchy; +} SequenceComplete_In; +typedef struct { + TPM2B_DIGEST result; + TPMT_TK_HASHCHECK validation; +} SequenceComplete_Out; +WOLFSSL_API TPM_RC TPM2_SequenceComplete(SequenceComplete_In* in, + SequenceComplete_Out* out); + + +typedef struct { + TPMI_DH_PCR pcrHandle; + TPMI_DH_OBJECT sequenceHandle; + TPM2B_MAX_BUFFER buffer; +} EventSequenceComplete_In; +typedef struct { + TPML_DIGEST_VALUES results; +} EventSequenceComplete_Out; +WOLFSSL_API TPM_RC TPM2_EventSequenceComplete(EventSequenceComplete_In* in, + EventSequenceComplete_Out* out); + + +typedef struct { + TPMI_DH_OBJECT objectHandle; + TPMI_DH_OBJECT signHandle; + TPM2B_DATA qualifyingData; + TPMT_SIG_SCHEME inScheme; +} Certify_In; +typedef struct { + TPM2B_ATTEST certifyInfo; + TPMT_SIGNATURE signature; +} Certify_Out; +WOLFSSL_API TPM_RC TPM2_Certify(Certify_In* in, Certify_Out* out); + + +typedef struct { + TPMI_DH_OBJECT signHandle; + TPMI_DH_OBJECT objectHandle; + TPM2B_DATA qualifyingData; + TPM2B_DIGEST creationHash; + TPMT_SIG_SCHEME inScheme; + TPMT_TK_CREATION creationTicket; +} CertifyCreation_In; +typedef struct { + TPM2B_ATTEST certifyInfo; + TPMT_SIGNATURE signature; +} CertifyCreation_Out; +WOLFSSL_API TPM_RC TPM2_CertifyCreation(CertifyCreation_In* in, CertifyCreation_Out* out); + + +typedef struct { + TPMI_DH_OBJECT signHandle; + TPM2B_DATA qualifyingData; + TPMT_SIG_SCHEME inScheme; + TPML_PCR_SELECTION PCRselect; +} Quote_In; +typedef struct { + TPM2B_ATTEST quoted; + TPMT_SIGNATURE signature; +} Quote_Out; +WOLFSSL_API TPM_RC TPM2_Quote(Quote_In* in, Quote_Out* out); + +typedef struct { + TPMI_RH_ENDORSEMENT privacyAdminHandle; + TPMI_DH_OBJECT signHandle; + TPMI_SH_HMAC sessionHandle; + TPM2B_DATA qualifyingData; + TPMT_SIG_SCHEME inScheme; +} GetSessionAuditDigest_In; +typedef struct { + TPM2B_ATTEST auditInfo; + TPMT_SIGNATURE signature; +} GetSessionAuditDigest_Out; +WOLFSSL_API TPM_RC TPM2_GetSessionAuditDigest(GetSessionAuditDigest_In* in, + GetSessionAuditDigest_Out* out); + +typedef struct { + TPMI_RH_ENDORSEMENT privacyHandle; + TPMI_DH_OBJECT signHandle; + TPM2B_DATA qualifyingData; + TPMT_SIG_SCHEME inScheme; +} GetCommandAuditDigest_In; +typedef struct { + TPM2B_ATTEST auditInfo; + TPMT_SIGNATURE signature; +} GetCommandAuditDigest_Out; +WOLFSSL_API TPM_RC TPM2_GetCommandAuditDigest(GetCommandAuditDigest_In* in, + GetCommandAuditDigest_Out* out); + +typedef struct { + TPMI_RH_ENDORSEMENT privacyAdminHandle; + TPMI_DH_OBJECT signHandle; + TPM2B_DATA qualifyingData; + TPMT_SIG_SCHEME inScheme; +} GetTime_In; +typedef struct { + TPM2B_ATTEST timeInfo; + TPMT_SIGNATURE signature; +} GetTime_Out; +WOLFSSL_API TPM_RC TPM2_GetTime(GetTime_In* in, GetTime_Out* out); + +typedef struct { + TPMI_DH_OBJECT signHandle; + TPM2B_ECC_POINT P1; + TPM2B_SENSITIVE_DATA s2; + TPM2B_ECC_PARAMETER y2; +} Commit_In; +typedef struct { + TPM2B_ECC_POINT K; + TPM2B_ECC_POINT L; + TPM2B_ECC_POINT E; + UINT16 counter; +} Commit_Out; +WOLFSSL_API TPM_RC TPM2_Commit(Commit_In* in, Commit_Out* out); + + +typedef struct { + TPMI_ECC_CURVE curveID; +} EC_Ephemeral_In; +typedef struct { + TPM2B_ECC_POINT Q; + UINT16 counter; +} EC_Ephemeral_Out; +WOLFSSL_API TPM_RC TPM2_EC_Ephemeral(EC_Ephemeral_In* in, + EC_Ephemeral_Out* out); + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPM2B_DIGEST digest; + TPMT_SIGNATURE signature; +} VerifySignature_In; +typedef struct { + TPMT_TK_VERIFIED validation; +} VerifySignature_Out; +WOLFSSL_API TPM_RC TPM2_VerifySignature(VerifySignature_In* in, + VerifySignature_Out* out); + + +typedef struct { + TPMI_DH_OBJECT keyHandle; + TPM2B_DIGEST digest; + TPMT_SIG_SCHEME inScheme; + TPMT_TK_HASHCHECK validation; +} Sign_In; +typedef struct { + TPMT_SIGNATURE signature; +} Sign_Out; +WOLFSSL_API TPM_RC TPM2_Sign(Sign_In* in, Sign_Out* out); + + +typedef struct { + TPMI_RH_PROVISION auth; + TPMI_ALG_HASH auditAlg; + TPML_CC setList; + TPML_CC clearList; +} SetCommandCodeAuditStatus_In; +WOLFSSL_API TPM_RC TPM2_SetCommandCodeAuditStatus( + SetCommandCodeAuditStatus_In* in); + + +typedef struct { + TPMI_DH_PCR pcrHandle; + TPM2B_EVENT eventData; +} PCR_Event_In; +typedef struct { + TPML_DIGEST_VALUES digests; +} PCR_Event_Out; +WOLFSSL_API TPM_RC TPM2_PCR_Event(PCR_Event_In* in, PCR_Event_Out* out); + + +typedef struct { + TPMI_RH_PLATFORM authHandle; + TPML_PCR_SELECTION pcrAllocation; +} PCR_Allocate_In; +typedef struct { + TPMI_YES_NO allocationSuccess; + UINT32 maxPCR; + UINT32 sizeNeeded; + UINT32 sizeAvailable; +} PCR_Allocate_Out; +WOLFSSL_API TPM_RC TPM2_PCR_Allocate(PCR_Allocate_In* in, + PCR_Allocate_Out* out); + +typedef struct { + TPMI_RH_PLATFORM authHandle; + TPM2B_DIGEST authPolicy; + TPMI_ALG_HASH hashAlg; + TPMI_DH_PCR pcrNum; +} PCR_SetAuthPolicy_In; +WOLFSSL_API TPM_RC TPM2_PCR_SetAuthPolicy(PCR_SetAuthPolicy_In* in); + +typedef struct { + TPMI_DH_PCR pcrHandle; + TPM2B_DIGEST auth; +} PCR_SetAuthValue_In; +WOLFSSL_API TPM_RC TPM2_PCR_SetAuthValue(PCR_SetAuthValue_In* in); + +typedef struct { + TPMI_DH_PCR pcrHandle; +} PCR_Reset_In; +WOLFSSL_API TPM_RC TPM2_PCR_Reset(PCR_Reset_In* in); + + +typedef struct { + TPMI_DH_OBJECT authObject; + TPMI_SH_POLICY policySession; + TPM2B_NONCE nonceTPM; + TPM2B_DIGEST cpHashA; + TPM2B_NONCE policyRef; + INT32 expiration; + TPMT_SIGNATURE auth; +} PolicySigned_In; +typedef struct { + TPM2B_TIMEOUT timeout; + TPMT_TK_AUTH policyTicket; +} PolicySigned_Out; +WOLFSSL_API TPM_RC TPM2_PolicySigned(PolicySigned_In* in, + PolicySigned_Out* out); + +typedef struct { + TPMI_DH_ENTITY authHandle; + TPMI_SH_POLICY policySession; + TPM2B_NONCE nonceTPM; + TPM2B_DIGEST cpHashA; + TPM2B_NONCE policyRef; + INT32 expiration; +} PolicySecret_In; +typedef struct { + TPM2B_TIMEOUT timeout; + TPMT_TK_AUTH policyTicket; +} PolicySecret_Out; +WOLFSSL_API TPM_RC TPM2_PolicySecret(PolicySecret_In* in, + PolicySecret_Out* out); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_TIMEOUT timeout; + TPM2B_DIGEST cpHashA; + TPM2B_NONCE policyRef; + TPM2B_NAME authName; + TPMT_TK_AUTH ticket; +} PolicyTicket_In; +WOLFSSL_API TPM_RC TPM2_PolicyTicket(PolicyTicket_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPML_DIGEST pHashList; +} PolicyOR_In; +WOLFSSL_API TPM_RC TPM2_PolicyOR(PolicyOR_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_DIGEST pcrDigest; + TPML_PCR_SELECTION pcrs; +} PolicyPCR_In; +WOLFSSL_API TPM_RC TPM2_PolicyPCR(PolicyPCR_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPMA_LOCALITY locality; +} PolicyLocality_In; +WOLFSSL_API TPM_RC TPM2_PolicyLocality(PolicyLocality_In* in); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; + TPMI_SH_POLICY policySession; + TPM2B_OPERAND operandB; + UINT16 offset; + TPM_EO operation; +} PolicyNV_In; +WOLFSSL_API TPM_RC TPM2_PolicyNV(PolicyNV_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_OPERAND operandB; + UINT16 offset; + TPM_EO operation; +} PolicyCounterTimer_In; +WOLFSSL_API TPM_RC TPM2_PolicyCounterTimer(PolicyCounterTimer_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM_CC code; +} PolicyCommandCode_In; +WOLFSSL_API TPM_RC TPM2_PolicyCommandCode(PolicyCommandCode_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; +} PolicyPhysicalPresence_In; +WOLFSSL_API TPM_RC TPM2_PolicyPhysicalPresence(PolicyPhysicalPresence_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_DIGEST cpHashA; +} PolicyCpHash_In; +WOLFSSL_API TPM_RC TPM2_PolicyCpHash(PolicyCpHash_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_DIGEST nameHash; +} PolicyNameHash_In; +WOLFSSL_API TPM_RC TPM2_PolicyNameHash(PolicyNameHash_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_NAME objectName; + TPM2B_NAME newParentName; + TPMI_YES_NO includeObject; +} PolicyDuplicationSelect_In; +WOLFSSL_API TPM_RC TPM2_PolicyDuplicationSelect(PolicyDuplicationSelect_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_DIGEST approvedPolicy; + TPM2B_NONCE policyRef; + TPM2B_NAME keySign; + TPMT_TK_VERIFIED checkTicket; +} PolicyAuthorize_In; +WOLFSSL_API TPM_RC TPM2_PolicyAuthorize(PolicyAuthorize_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; +} PolicyAuthValue_In; +WOLFSSL_API TPM_RC TPM2_PolicyAuthValue(PolicyAuthValue_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; +} PolicyPassword_In; +WOLFSSL_API TPM_RC TPM2_PolicyPassword(PolicyPassword_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; +} PolicyGetDigest_In; +typedef struct { + TPM2B_DIGEST policyDigest; +} PolicyGetDigest_Out; +WOLFSSL_API TPM_RC TPM2_PolicyGetDigest(PolicyGetDigest_In* in, PolicyGetDigest_Out* out); + +typedef struct { + TPMI_SH_POLICY policySession; + TPMI_YES_NO writtenSet; +} PolicyNvWritten_In; +WOLFSSL_API TPM_RC TPM2_PolicyNvWritten(PolicyNvWritten_In* in); + +typedef struct { + TPMI_SH_POLICY policySession; + TPM2B_DIGEST templateHash; +} PolicyTemplate_In; +WOLFSSL_API TPM_RC TPM2_PolicyTemplate(PolicyTemplate_In* in); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; + TPMI_SH_POLICY policySession; +} PolicyAuthorizeNV_In; +WOLFSSL_API TPM_RC TPM2_PolicyAuthorizeNV(PolicyAuthorizeNV_In* in); + + + +WOLFSSL_API void _TPM_Hash_Start(void); +WOLFSSL_API void _TPM_Hash_Data(UINT32 dataSize, BYTE *data); +WOLFSSL_API void _TPM_Hash_End(void); + + +typedef struct { + TPMI_RH_HIERARCHY authHandle; + TPMI_RH_ENABLES enable; + TPMI_YES_NO state; +} HierarchyControl_In; +WOLFSSL_API TPM_RC TPM2_HierarchyControl(HierarchyControl_In* in); + +typedef struct { + TPMI_RH_HIERARCHY_AUTH authHandle; + TPM2B_DIGEST authPolicy; + TPMI_ALG_HASH hashAlg; +} SetPrimaryPolicy_In; +WOLFSSL_API TPM_RC TPM2_SetPrimaryPolicy(SetPrimaryPolicy_In* in); + + +typedef struct { + TPMI_RH_PLATFORM authHandle; +} ChangePPS_In; +WOLFSSL_API TPM_RC TPM2_ChangePPS(ChangePPS_In* in); + +typedef struct { + TPMI_RH_PLATFORM authHandle; +} ChangeEPS_In; +WOLFSSL_API TPM_RC TPM2_ChangeEPS(ChangeEPS_In* in); + + +typedef struct { + TPMI_RH_CLEAR authHandle; +} Clear_In; +WOLFSSL_API TPM_RC TPM2_Clear(Clear_In* in); + +typedef struct { + TPMI_RH_CLEAR auth; + TPMI_YES_NO disable; +} ClearControl_In; +WOLFSSL_API TPM_RC TPM2_ClearControl(ClearControl_In* in); + +typedef struct { + TPMI_RH_HIERARCHY_AUTH authHandle; + TPM2B_AUTH newAuth; +} HierarchyChangeAuth_In; +WOLFSSL_API TPM_RC TPM2_HierarchyChangeAuth(HierarchyChangeAuth_In* in); + +typedef struct { + TPMI_RH_LOCKOUT lockHandle; +} DictionaryAttackLockReset_In; +WOLFSSL_API TPM_RC TPM2_DictionaryAttackLockReset(DictionaryAttackLockReset_In* in); + +typedef struct { + TPMI_RH_LOCKOUT lockHandle; + UINT32 newMaxTries; + UINT32 newRecoveryTime; + UINT32 lockoutRecovery; +} DictionaryAttackParameters_In; +WOLFSSL_API TPM_RC TPM2_DictionaryAttackParameters(DictionaryAttackParameters_In* in); + + +typedef struct { + TPMI_RH_PLATFORM auth; + TPML_CC setList; + TPML_CC clearList; +} PP_Commands_In; +WOLFSSL_API TPM_RC TPM2_PP_Commands(PP_Commands_In* in); + +typedef struct { + TPMI_RH_PLATFORM authHandle; + UINT32 algorithmSet; +} SetAlgorithmSet_In; +WOLFSSL_API TPM_RC TPM2_SetAlgorithmSet(SetAlgorithmSet_In* in); + +typedef struct { + TPMI_RH_PLATFORM authorization; + TPMI_DH_OBJECT keyHandle; + TPM2B_DIGEST fuDigest; + TPMT_SIGNATURE manifestSignature; +} FieldUpgradeStart_In; +WOLFSSL_API TPM_RC TPM2_FieldUpgradeStart(FieldUpgradeStart_In* in); + +typedef struct { + TPM2B_MAX_BUFFER fuData; +} FieldUpgradeData_In; +typedef struct { + TPMT_HA nextDigest; + TPMT_HA firstDigest; +} FieldUpgradeData_Out; +WOLFSSL_API TPM_RC TPM2_FieldUpgradeData(FieldUpgradeData_In* in, + FieldUpgradeData_Out* out); + +typedef struct { + UINT32 sequenceNumber; +} FirmwareRead_In; +typedef struct { + TPM2B_MAX_BUFFER fuData; +} FirmwareRead_Out; +WOLFSSL_API TPM_RC TPM2_FirmwareRead(FirmwareRead_In* in, FirmwareRead_Out* out); + + +typedef struct { + TPMI_DH_CONTEXT saveHandle; +} ContextSave_In; +typedef struct { + TPMS_CONTEXT context; +} ContextSave_Out; +WOLFSSL_API TPM_RC TPM2_ContextSave(ContextSave_In* in, ContextSave_Out* out); + +typedef struct { + TPMS_CONTEXT context; +} ContextLoad_In; +typedef struct { + TPMI_DH_CONTEXT loadedHandle; +} ContextLoad_Out; +WOLFSSL_API TPM_RC TPM2_ContextLoad(ContextLoad_In* in, ContextLoad_Out* out); + + +typedef struct { + TPMI_RH_PROVISION auth; + TPMI_DH_OBJECT objectHandle; + TPMI_DH_PERSISTENT persistentHandle; +} EvictControl_In; +WOLFSSL_API TPM_RC TPM2_EvictControl(EvictControl_In* in); + + +typedef struct { + TPMS_TIME_INFO currentTime; +} ReadClock_Out; +WOLFSSL_API TPM_RC TPM2_ReadClock(ReadClock_Out* out); + +typedef struct { + TPMI_RH_PROVISION auth; + UINT64 newTime; +} ClockSet_In; +WOLFSSL_API TPM_RC TPM2_ClockSet(ClockSet_In* in); + +typedef struct { + TPMI_RH_PROVISION auth; + TPM_CLOCK_ADJUST rateAdjust; +} ClockRateAdjust_In; +WOLFSSL_API TPM_RC TPM2_ClockRateAdjust(ClockRateAdjust_In* in); + + +typedef struct { + TPMT_PUBLIC_PARMS parameters; +} TestParms_In; +WOLFSSL_API TPM_RC TPM2_TestParms(TestParms_In* in); + + +typedef struct { + TPMI_RH_PROVISION authHandle; + TPM2B_AUTH auth; + TPM2B_NV_PUBLIC publicInfo; +} NV_DefineSpace_In; +WOLFSSL_API TPM_RC TPM2_NV_DefineSpace(NV_DefineSpace_In* in); + +typedef struct { + TPMI_RH_PROVISION authHandle; + TPMI_RH_NV_INDEX nvIndex; +} NV_UndefineSpace_In; +WOLFSSL_API TPM_RC TPM2_NV_UndefineSpace(NV_UndefineSpace_In* in); + +typedef struct { + TPMI_RH_NV_INDEX nvIndex; + TPMI_RH_PLATFORM platform; +} NV_UndefineSpaceSpecial_In; +WOLFSSL_API TPM_RC TPM2_NV_UndefineSpaceSpecial(NV_UndefineSpaceSpecial_In* in); + +typedef struct { + TPMI_RH_NV_INDEX nvIndex; +} NV_ReadPublic_In; +typedef struct { + TPM2B_NV_PUBLIC nvPublic; + TPM2B_NAME nvName; +} NV_ReadPublic_Out; +WOLFSSL_API TPM_RC TPM2_NV_ReadPublic(NV_ReadPublic_In* in, NV_ReadPublic_Out* out); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; + TPM2B_MAX_NV_BUFFER data; + UINT16 offset; +} NV_Write_In; +WOLFSSL_API TPM_RC TPM2_NV_Write(NV_Write_In* in); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; +} NV_Increment_In; +WOLFSSL_API TPM_RC TPM2_NV_Increment(NV_Increment_In* in); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; + TPM2B_MAX_NV_BUFFER data; +} NV_Extend_In; +WOLFSSL_API TPM_RC TPM2_NV_Extend(NV_Extend_In* in); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; + UINT64 bits; +} NV_SetBits_In; +WOLFSSL_API TPM_RC TPM2_NV_SetBits(NV_SetBits_In* in); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; +} NV_WriteLock_In; +WOLFSSL_API TPM_RC TPM2_NV_WriteLock(NV_WriteLock_In* in); + +typedef struct { + TPMI_RH_PROVISION authHandle; +} NV_GlobalWriteLock_In; +WOLFSSL_API TPM_RC TPM2_NV_GlobalWriteLock(NV_GlobalWriteLock_In* in); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; + UINT16 size; + UINT16 offset; +} NV_Read_In; +typedef struct { + TPM2B_MAX_NV_BUFFER data; +} NV_Read_Out; +WOLFSSL_API TPM_RC TPM2_NV_Read(NV_Read_In* in, NV_Read_Out* out); + +typedef struct { + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; +} NV_ReadLock_In; +WOLFSSL_API TPM_RC TPM2_NV_ReadLock(NV_ReadLock_In* in); + +typedef struct { + TPMI_RH_NV_INDEX nvIndex; + TPM2B_AUTH newAuth; +} NV_ChangeAuth_In; +WOLFSSL_API TPM_RC TPM2_NV_ChangeAuth(NV_ChangeAuth_In* in); + +typedef struct { + TPMI_DH_OBJECT signHandle; + TPMI_RH_NV_AUTH authHandle; + TPMI_RH_NV_INDEX nvIndex; + TPM2B_DATA qualifyingData; + TPMT_SIG_SCHEME inScheme; + UINT16 size; + UINT16 offset; +} NV_Certify_In; +typedef struct { + TPM2B_ATTEST certifyInfo; + TPMT_SIGNATURE signature; +} NV_Certify_Out; +WOLFSSL_API TPM_RC TPM2_NV_Certify(NV_Certify_In* in, NV_Certify_Out* out); + + +/* Helper API's - Not based on spec */ +WOLFSSL_API int TPM2_GetHashDigestSize(TPMI_ALG_HASH hashAlg); +WOLFSSL_API const char* TPM2_GetAlgName(TPM_ALG_ID alg); +WOLFSSL_API const char* TPM2_GetRCString(TPM_RC rc); +WOLFSSL_API void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, int pcrIndex); + +#endif /* __TPM2_H__ */ diff --git a/wolftpm/version.h b/wolftpm/version.h new file mode 100644 index 0000000..8e5ddc1 --- /dev/null +++ b/wolftpm/version.h @@ -0,0 +1,42 @@ +/* version.h.in + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* + * The version header provides the current version number to the code + * based and is updated automatically by the configure script. A copy + * of the last generated copy of version.h is included with the + * distribution for environments that do not use configure. + */ + + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBWOLFTPM_VERSION_STRING "0.1.0" +#define LIBWOLFTPM_VERSION_HEX 0x00001000 + +#ifdef __cplusplus +} +#endif diff --git a/wolftpm/version.h.in b/wolftpm/version.h.in new file mode 100644 index 0000000..8c00ba9 --- /dev/null +++ b/wolftpm/version.h.in @@ -0,0 +1,42 @@ +/* version.h.in + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* + * The version header provides the current version number to the code + * based and is updated automatically by the configure script. A copy + * of the last generated copy of version.h is included with the + * distribution for environments that do not use configure. + */ + + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBWOLFTPM_VERSION_STRING "@VERSION@" +#define LIBWOLFTPM_VERSION_HEX @HEX_VERSION@ + +#ifdef __cplusplus +} +#endif diff --git a/wolftpm/visibility.h b/wolftpm/visibility.h new file mode 100755 index 0000000..ed0d400 --- /dev/null +++ b/wolftpm/visibility.h @@ -0,0 +1,61 @@ +/* visibility.h + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfMQTT. + * + * wolfMQTT is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfMQTT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Visibility control macros */ + +#ifndef WOLFMQTT_VISIBILITY_H +#define WOLFMQTT_VISIBILITY_H + +/* WOLFMQTT_API is used for the public API symbols. + It either imports or exports (or does nothing for static builds) + + WOLFMQTT_LOCAL is used for non-API symbols (private). +*/ + +#if defined(BUILDING_WOLFMQTT) + #if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY + #define WOLFMQTT_API __attribute__ ((visibility("default"))) + #define WOLFMQTT_LOCAL __attribute__ ((visibility("hidden"))) + #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) + #define WOLFMQTT_API __global + #define WOLFMQTT_LOCAL __hidden + #elif defined(_MSC_VER) + #ifdef _WINDLL + #define WOLFMQTT_API __declspec(dllexport) + #else + #define WOLFMQTT_API + #endif + #define WOLFMQTT_LOCAL + #else + #define WOLFMQTT_API + #define WOLFMQTT_LOCAL + #endif /* HAVE_VISIBILITY */ +#else /* BUILDING_WOLFMQTT */ + #if defined(_MSC_VER) + #define WOLFMQTT_API __declspec(dllimport) + #define WOLFMQTT_LOCAL + #else + #define WOLFMQTT_API + #define WOLFMQTT_LOCAL + #endif +#endif /* BUILDING_WOLFMQTT */ + +#endif /* WOLFMQTT_VISIBILITY_H */