| /* Microsoft Reference Implementation for TPM 2.0 | |
| * | |
| * The copyright in this software is being made available under the BSD License, | |
| * included below. This software may be subject to other third party and | |
| * contributor rights, including patent rights, and no such rights are granted | |
| * under this license. | |
| * | |
| * Copyright (c) Microsoft Corporation | |
| * | |
| * All rights reserved. | |
| * | |
| * BSD License | |
| * | |
| * 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. | |
| * | |
| * 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 HOLDER 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. | |
| */ | |
| //** Introduction | |
| // This file contains the definitions needed for defining the internal BIGNUM | |
| // structure. | |
| // A BIGNUM is a pointer to a structure. The structure has three fields. The | |
| // last field is and array (d) of crypt_uword_t. Each word is in machine format | |
| // (big- or little-endian) with the words in ascending significance (i.e. words | |
| // in little-endian order). This is the order that seems to be used in every | |
| // big number library in the worlds, so... | |
| // | |
| // The first field in the structure (allocated) is the number of words in 'd'. | |
| // This is the upper limit on the size of the number that can be held in the | |
| // structure. This differs from libraries like OpenSSL as this is not intended | |
| // to deal with numbers of arbitrary size; just numbers that are needed to deal | |
| // with the algorithms that are defined in the TPM implementation. | |
| // | |
| // The second field in the structure (size) is the number of significant words | |
| // in 'n'. When this number is zero, the number is zero. The word at used-1 should | |
| // never be zero. All words between d[size] and d[allocated-1] should be zero. | |
| //** Defines | |
| #ifndef _BN_NUMBERS_H | |
| #define _BN_NUMBERS_H | |
| #if RADIX_BITS == 64 | |
| # define RADIX_LOG2 6 | |
| #elif RADIX_BITS == 32 | |
| #define RADIX_LOG2 5 | |
| #else | |
| # error "Unsupported radix" | |
| #endif | |
| #define RADIX_MOD(x) ((x) & ((1 << RADIX_LOG2) - 1)) | |
| #define RADIX_DIV(x) ((x) >> RADIX_LOG2) | |
| #define RADIX_MASK ((((crypt_uword_t)1) << RADIX_LOG2) - 1) | |
| #define BITS_TO_CRYPT_WORDS(bits) RADIX_DIV((bits) + (RADIX_BITS - 1)) | |
| #define BYTES_TO_CRYPT_WORDS(bytes) BITS_TO_CRYPT_WORDS(bytes * 8) | |
| #define SIZE_IN_CRYPT_WORDS(thing) BYTES_TO_CRYPT_WORDS(sizeof(thing)) | |
| #if RADIX_BITS == 64 | |
| #define SWAP_CRYPT_WORD(x) REVERSE_ENDIAN_64(x) | |
| typedef uint64_t crypt_uword_t; | |
| typedef int64_t crypt_word_t; | |
| # define TO_CRYPT_WORD_64 BIG_ENDIAN_BYTES_TO_UINT64 | |
| # define TO_CRYPT_WORD_32(a, b, c, d) TO_CRYPT_WORD_64(0, 0, 0, 0, a, b, c, d) | |
| #elif RADIX_BITS == 32 | |
| # define SWAP_CRYPT_WORD(x) REVERSE_ENDIAN_32((x)) | |
| typedef uint32_t crypt_uword_t; | |
| typedef int32_t crypt_word_t; | |
| # define TO_CRYPT_WORD_64(a, b, c, d, e, f, g, h) \ | |
| BIG_ENDIAN_BYTES_TO_UINT32(e, f, g, h), \ | |
| BIG_ENDIAN_BYTES_TO_UINT32(a, b, c, d) | |
| #endif | |
| #define MAX_CRYPT_UWORD (~((crypt_uword_t)0)) | |
| #define MAX_CRYPT_WORD ((crypt_word_t)(MAX_CRYPT_UWORD >> 1)) | |
| #define MIN_CRYPT_WORD (~MAX_CRYPT_WORD) | |
| #define LARGEST_NUMBER (MAX((ALG_RSA * MAX_RSA_KEY_BYTES), \ | |
| MAX((ALG_ECC * MAX_ECC_KEY_BYTES), MAX_DIGEST_SIZE))) | |
| #define LARGEST_NUMBER_BITS (LARGEST_NUMBER * 8) | |
| #define MAX_ECC_PARAMETER_BYTES (MAX_ECC_KEY_BYTES * ALG_ECC) | |
| // These are the basic big number formats. This is convertible to the library- | |
| // specific format without too much difficulty. For the math performed using | |
| // these numbers, the value is always positive. | |
| #define BN_STRUCT_DEF(count) struct { \ | |
| crypt_uword_t allocated; \ | |
| crypt_uword_t size; \ | |
| crypt_uword_t d[count]; \ | |
| } | |
| typedef BN_STRUCT_DEF(1) bignum_t; | |
| #ifndef bigNum | |
| typedef bignum_t *bigNum; | |
| typedef const bignum_t *bigConst; | |
| #endif | |
| extern const bignum_t BnConstZero; | |
| // The Functions to access the properties of a big number. | |
| // Get number of allocated words | |
| #define BnGetAllocated(x) (unsigned)((x)->allocated) | |
| // Get number of words used | |
| #define BnGetSize(x) ((x)->size) | |
| // Get a pointer to the data array | |
| #define BnGetArray(x) ((crypt_uword_t *)&((x)->d[0])) | |
| // Get the nth word of a BIGNUM (zero-based) | |
| #define BnGetWord(x, i) (crypt_uword_t)((x)->d[i]) | |
| // Some things that are done often. | |
| // Test to see if a bignum_t is equal to zero | |
| #define BnEqualZero(bn) (BnGetSize(bn) == 0) | |
| // Test to see if a bignum_t is equal to a word type | |
| #define BnEqualWord(bn, word) \ | |
| ((BnGetSize(bn) == 1) && (BnGetWord(bn, 0) == (crypt_uword_t)word)) | |
| // Determine if a BIGNUM is even. A zero is even. Although the | |
| // indication that a number is zero is that its size is zero, | |
| // all words of the number are 0 so this test works on zero. | |
| #define BnIsEven(n) ((BnGetWord(n, 0) & 1) == 0) | |
| // The macros below are used to define BIGNUM values of the required | |
| // size. The values are allocated on the stack so they can be | |
| // treated like simple local values. | |
| // This will call the initialization function for a defined bignum_t. | |
| // This sets the allocated and used fields and clears the words of 'n'. | |
| #define BN_INIT(name) \ | |
| (bigNum)BnInit((bigNum)&(name), \ | |
| BYTES_TO_CRYPT_WORDS(sizeof(name.d))) | |
| // In some cases, a function will need the address of the structure | |
| // associated with a variable. The structure for a BIGNUM variable | |
| // of 'name' is 'name_'. Generally, when the structure is created, it | |
| // is initialized and a parameter is created with a pointer to the | |
| // structure. The pointer has the 'name' and the structure it points | |
| // to is 'name_' | |
| #define BN_ADDRESS(name) (bigNum)&name##_ | |
| #define BN_CONST(name, words, initializer) \ | |
| typedef const struct name##_type { \ | |
| crypt_uword_t allocated; \ | |
| crypt_uword_t size; \ | |
| crypt_uword_t d[words < 1 ? 1 : words]; \ | |
| } name##_type; \ | |
| name##_type name = {(words < 1 ? 1 : words), words, {initializer}}; | |
| #define BN_STRUCT_ALLOCATION(bits) (BITS_TO_CRYPT_WORDS(bits) + 1) | |
| // Create a structure of the correct size. | |
| #define BN_STRUCT(bits) \ | |
| BN_STRUCT_DEF(BN_STRUCT_ALLOCATION(bits)) | |
| // Define a BIGNUM type with a specific allocation | |
| #define BN_TYPE(name, bits) \ | |
| typedef BN_STRUCT(bits) bn_##name##_t | |
| // This creates a local BIGNUM variable of a specific size and | |
| // initializes it from a TPM2B input parameter. | |
| #define BN_INITIALIZED(name, bits, initializer) \ | |
| BN_STRUCT(bits) name##_; \ | |
| bigNum name = BnFrom2B(BN_INIT(name##_), \ | |
| (const TPM2B *)initializer) | |
| // Create a local variable that can hold a number with 'bits' | |
| #define BN_VAR(name, bits) \ | |
| BN_STRUCT(bits) _##name; \ | |
| bigNum name = BN_INIT(_##name) | |
| // Create a type that can hold the largest number defined by the | |
| // implementation. | |
| #define BN_MAX(name) BN_VAR(name, LARGEST_NUMBER_BITS) | |
| #define BN_MAX_INITIALIZED(name, initializer) \ | |
| BN_INITIALIZED(name, LARGEST_NUMBER_BITS, initializer) | |
| // A word size value is useful | |
| #define BN_WORD(name) BN_VAR(name, RADIX_BITS) | |
| // This is used to create a word-size BIGNUM and initialize it with | |
| // an input parameter to a function. | |
| #define BN_WORD_INITIALIZED(name, initial) \ | |
| BN_STRUCT(RADIX_BITS) name##_; \ | |
| bigNum name = BnInitializeWord((bigNum)&name##_, \ | |
| BN_STRUCT_ALLOCATION(RADIX_BITS), initial) | |
| // ECC-Specific Values | |
| // This is the format for a point. It is always in affine format. The Z value is | |
| // carried as part of the point, primarily to simplify the interface to the support | |
| // library. Rather than have the interface layer have to create space for the | |
| // point each time it is used... | |
| // The x, y, and z values are pointers to bigNum values and not in-line versions of | |
| // the numbers. This is a relic of the days when there was no standard TPM format | |
| // for the numbers | |
| typedef struct _bn_point_t | |
| { | |
| bigNum x; | |
| bigNum y; | |
| bigNum z; | |
| } bn_point_t; | |
| typedef bn_point_t *bigPoint; | |
| typedef const bn_point_t *pointConst; | |
| typedef struct constant_point_t | |
| { | |
| bigConst x; | |
| bigConst y; | |
| bigConst z; | |
| } constant_point_t; | |
| #define ECC_BITS (MAX_ECC_KEY_BYTES * 8) | |
| BN_TYPE(ecc, ECC_BITS); | |
| #define ECC_NUM(name) BN_VAR(name, ECC_BITS) | |
| #define ECC_INITIALIZED(name, initializer) \ | |
| BN_INITIALIZED(name, ECC_BITS, initializer) | |
| #define POINT_INSTANCE(name, bits) \ | |
| BN_STRUCT (bits) name##_x = \ | |
| {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \ | |
| BN_STRUCT ( bits ) name##_y = \ | |
| {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \ | |
| BN_STRUCT ( bits ) name##_z = \ | |
| {BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \ | |
| bn_point_t name##_ | |
| #define POINT_INITIALIZER(name) \ | |
| BnInitializePoint(&name##_, (bigNum)&name##_x, \ | |
| (bigNum)&name##_y, (bigNum)&name##_z) | |
| #define POINT_INITIALIZED(name, initValue) \ | |
| POINT_INSTANCE(name, MAX_ECC_KEY_BITS); \ | |
| bigPoint name = BnPointFrom2B( \ | |
| POINT_INITIALIZER(name), \ | |
| initValue) | |
| #define POINT_VAR(name, bits) \ | |
| POINT_INSTANCE (name, bits); \ | |
| bigPoint name = POINT_INITIALIZER(name) | |
| #define POINT(name) POINT_VAR(name, MAX_ECC_KEY_BITS) | |
| // Structure for the curve parameters. This is an analog to the | |
| // TPMS_ALGORITHM_DETAIL_ECC | |
| typedef struct | |
| { | |
| bigConst prime; // a prime number | |
| bigConst order; // the order of the curve | |
| bigConst h; // cofactor | |
| bigConst a; // linear coefficient | |
| bigConst b; // constant term | |
| constant_point_t base; // base point | |
| } ECC_CURVE_DATA; | |
| // Access macros for the ECC_CURVE structure. The parameter 'C' is a pointer | |
| // to an ECC_CURVE_DATA structure. In some libraries, the curve structure contains | |
| // a pointer to an ECC_CURVE_DATA structure as well as some other bits. For those | |
| // cases, the AccessCurveData macro is used in the code to first get the pointer | |
| // to the ECC_CURVE_DATA for access. In some cases, the macro does nothing. | |
| #define CurveGetPrime(C) ((C)->prime) | |
| #define CurveGetOrder(C) ((C)->order) | |
| #define CurveGetCofactor(C) ((C)->h) | |
| #define CurveGet_a(C) ((C)->a) | |
| #define CurveGet_b(C) ((C)->b) | |
| #define CurveGetG(C) ((pointConst)&((C)->base)) | |
| #define CurveGetGx(C) ((C)->base.x) | |
| #define CurveGetGy(C) ((C)->base.y) | |
| // Convert bytes in initializers | |
| // This is used for CryptEccData.c. | |
| #define BIG_ENDIAN_BYTES_TO_UINT32(a, b, c, d) \ | |
| ( ((UINT32)(a) << 24) \ | |
| + ((UINT32)(b) << 16) \ | |
| + ((UINT32)(c) << 8) \ | |
| + ((UINT32)(d)) \ | |
| ) | |
| #define BIG_ENDIAN_BYTES_TO_UINT64(a, b, c, d, e, f, g, h) \ | |
| ( ((UINT64)(a) << 56) \ | |
| + ((UINT64)(b) << 48) \ | |
| + ((UINT64)(c) << 40) \ | |
| + ((UINT64)(d) << 32) \ | |
| + ((UINT64)(e) << 24) \ | |
| + ((UINT64)(f) << 16) \ | |
| + ((UINT64)(g) << 8) \ | |
| + ((UINT64)(h)) \ | |
| ) | |
| #ifndef RADIX_BYTES | |
| # if RADIX_BITS == 32 | |
| # define RADIX_BYTES 4 | |
| # elif RADIX_BITS == 64 | |
| # define RADIX_BYTES 8 | |
| # else | |
| # error "RADIX_BITS must either be 32 or 64" | |
| # endif | |
| #endif | |
| // These macros are used for data initialization of big number ECC constants | |
| // These two macros combine a macro for data definition with a macro for | |
| // structure initilization. The 'a' parameter is a macro that gives numbers to | |
| // each of the bytes of the initializer and defines where each of the numberd | |
| // bytes will show up in the final structure. The 'b' value is a structure that | |
| // contains the requisite number of bytes in big endian order. S, the MJOIN | |
| // and JOIND macros will combine a macro defining a data layout with a macro defining | |
| // the data to be places. Generally, these macros will only need expansion when | |
| // CryptEccData.c gets compiled. | |
| #define JOINED(a,b) a b | |
| #define MJOIN(a,b) a b | |
| #define B4_TO_BN(a, b, c, d) (((((a << 8) + b) << 8) + c) + d) | |
| #if RADIX_BYTES == 64 | |
| #define B8_TO_BN(a, b, c, d, e, f, g, h) \ | |
| (UINT64)(((((((((((((((a) << 8) | b) << 8) | c) << 8) | d) << 8) \ | |
| e) << 8) | f) << 8) | g) << 8) | h) | |
| #define B1_TO_BN(a) B8_TO_BN(0, 0, 0, 0, 0, 0, 0, a) | |
| #define B2_TO_BN(a, b) B8_TO_BN(0, 0, 0, 0, 0, 0, a, b) | |
| #define B3_TO_BN(a, b, c) B8_TO_BN(0, 0, 0, 0, 0, a, b, c) | |
| #define B4_TO_BN(a, b, c, d) B8_TO_BN(0, 0, 0, 0, a, b, c, d) | |
| #define B5_TO_BN(a, b, c, d, e) B8_TO_BN(0, 0, 0, a, b, c, d, e) | |
| #define B6_TO_BN(a, b, c, d, e, f) B8_TO_BN(0, 0, a, b, c, d, e, f) | |
| #define B7_TO_BN(a, b, c, d, e, f, g) B8_TO_BN(0, a, b, c, d, e, f, g) | |
| #else | |
| #define B1_TO_BN(a) B4_TO_BN(0, 0, 0, a) | |
| #define B2_TO_BN(a, b) B4_TO_BN(0, 0, a, b) | |
| #define B3_TO_BN(a, b, c) B4_TO_BN(0, a, b, c) | |
| #define B4_TO_BN(a, b, c, d) (((((a << 8) + b) << 8) + c) + d) | |
| #define B5_TO_BN(a, b, c, d, e) B4_TO_BN(b, c, d, e), B1_TO_BN(a) | |
| #define B6_TO_BN(a, b, c, d, e, f) B4_TO_BN(c, d, e, f), B2_TO_BN(a, b) | |
| #define B7_TO_BN(a, b, c, d, e, f, g) B4_TO_BN(d, e, f, g), B3_TO_BN(a, b, c) | |
| #define B8_TO_BN(a, b, c, d, e, f, g, h) B4_TO_BN(e, f, g, h), B4_TO_BN(a, b, c, d) | |
| #endif | |
| // Add implementation dependent definitions for other ECC Values and for linkages. | |
| #include LIB_INCLUDE(MATH_LIB, Math) | |
| #endif // _BN_NUMBERS_H |