1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2020, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <pkcs11_ta.h> 8 #include <tee_api_defines.h> 9 #include <tee_internal_api.h> 10 #include <util.h> 11 12 #include "attributes.h" 13 #include "processing.h" 14 15 /* 16 * DER encoded EC parameters generated with script: 17 * ta/pkcs11/scripts/dump_ec_curve_params.sh 18 */ 19 20 static const uint8_t prime192v1_name_der[] = { 21 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 22 0x01, 0x01, 23 }; 24 25 static const uint8_t secp224r1_name_der[] = { 26 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x21, 27 }; 28 29 static const uint8_t prime256v1_name_der[] = { 30 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 31 0x01, 0x07, 32 }; 33 34 static const uint8_t secp384r1_name_der[] = { 35 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 36 }; 37 38 static const uint8_t secp521r1_name_der[] = { 39 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, 40 }; 41 42 static const uint8_t prime192v1_oid_der[] = { 43 0x30, 0x81, 0xc7, 0x02, 0x01, 0x01, 0x30, 0x24, 44 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 45 0x01, 0x02, 0x19, 0x00, 0xff, 0xff, 0xff, 0xff, 46 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 47 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 48 0xff, 0xff, 0xff, 0xff, 0x30, 0x4b, 0x04, 0x18, 49 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 50 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 51 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 52 0x04, 0x18, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c, 53 0x80, 0xe7, 0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24, 54 0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46, 55 0xb9, 0xb1, 0x03, 0x15, 0x00, 0x30, 0x45, 0xae, 56 0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57, 0x95, 57 0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21, 0x96, 58 0xd5, 0x04, 0x31, 0x04, 0x18, 0x8d, 0xa8, 0x0e, 59 0xb0, 0x30, 0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb, 60 0x43, 0xa1, 0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd, 61 0x82, 0xff, 0x10, 0x12, 0x07, 0x19, 0x2b, 0x95, 62 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed, 63 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 64 0x1e, 0x79, 0x48, 0x11, 0x02, 0x19, 0x00, 0xff, 65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 66 0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14, 67 0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31, 0x02, 68 0x01, 0x01, 69 }; 70 71 static const uint8_t secp224r1_oid_der[] = { 72 0x30, 0x81, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x28, 73 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 74 0x01, 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 75 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 76 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 78 0x30, 0x53, 0x04, 0x1c, 0xff, 0xff, 0xff, 0xff, 79 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 80 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 81 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 82 0x04, 0x1c, 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04, 83 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44, 84 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b, 85 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, 0x03, 0x15, 86 0x00, 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7, 87 0xfc, 0xdc, 0x45, 0xb5, 0x9f, 0xa3, 0xb9, 0xab, 88 0x8f, 0x6a, 0x94, 0x8b, 0xc5, 0x04, 0x39, 0x04, 89 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 90 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, 91 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6, 92 0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88, 93 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, 94 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 95 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34, 96 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 97 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 98 0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, 0x13, 99 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, 0x02, 100 0x01, 0x01, 101 }; 102 103 static const uint8_t prime256v1_oid_der[] = { 104 0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c, 105 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 106 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 107 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 109 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 110 0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20, 111 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 114 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 115 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 116 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 117 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 118 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 119 0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36, 120 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78, 121 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 122 0x90, 0x04, 0x41, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 123 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 124 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 125 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 126 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2, 127 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 128 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 129 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 130 0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 131 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 133 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 134 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, 0x02, 135 0x01, 0x01, 136 }; 137 138 static const uint8_t secp384r1_oid_der[] = { 139 0x30, 0x82, 0x01, 0x57, 0x02, 0x01, 0x01, 0x30, 140 0x3c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 141 0x01, 0x01, 0x02, 0x31, 0x00, 0xff, 0xff, 0xff, 142 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 143 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 144 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 145 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 146 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 147 0x00, 0xff, 0xff, 0xff, 0xff, 0x30, 0x7b, 0x04, 148 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 149 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 150 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 152 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 153 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 154 0xfc, 0x04, 0x30, 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 155 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3, 156 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 157 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50, 158 0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a, 159 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3, 160 0xec, 0x2a, 0xef, 0x03, 0x15, 0x00, 0xa3, 0x35, 161 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00, 162 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd, 163 0xac, 0x73, 0x04, 0x61, 0x04, 0xaa, 0x87, 0xca, 164 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7, 165 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b, 166 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41, 167 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2, 168 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e, 169 0x38, 0x72, 0x76, 0x0a, 0xb7, 0x36, 0x17, 0xde, 170 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 171 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 172 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 173 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 174 0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 175 0x7c, 0x90, 0xea, 0x0e, 0x5f, 0x02, 0x31, 0x00, 176 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 177 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 178 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 179 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf, 180 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a, 181 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73, 182 0x02, 0x01, 0x01, 183 }; 184 185 static const uint8_t secp521r1_oid_der[] = { 186 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 187 0x4d, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 188 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 189 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 190 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 191 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 192 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 193 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 194 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 195 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 196 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x81, 197 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 198 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 199 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 200 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 201 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 202 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 203 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 204 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 205 0xff, 0xff, 0xff, 0xff, 0xfc, 0x04, 0x42, 0x00, 206 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 207 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 208 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15, 209 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09, 210 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 211 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf, 212 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 213 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 214 0x00, 0x03, 0x15, 0x00, 0xd0, 0x9e, 0x88, 0x00, 215 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17, 216 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 217 0x04, 0x81, 0x85, 0x04, 0x00, 0xc6, 0x85, 0x8e, 218 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 219 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 220 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28, 221 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 222 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 223 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48, 224 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 225 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 226 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 227 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 228 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 229 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 230 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 231 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 232 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 233 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 234 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 235 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 236 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 237 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 238 0xff, 0xff, 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83, 239 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 240 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 241 0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 242 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01, 243 }; 244 245 struct supported_ecc_curve { 246 const uint8_t *oid_der; 247 size_t oid_size; 248 const uint8_t *name_der; 249 size_t name_size; 250 size_t key_size; 251 uint32_t tee_id; 252 const char *label; 253 size_t label_size; 254 }; 255 256 #define ECC_CURVE(_tee_id, _key_size, _label) \ 257 { \ 258 .tee_id = (_tee_id), \ 259 .key_size = (_key_size), \ 260 .oid_der = _label ## _oid_der, \ 261 .oid_size = sizeof(_label ## _oid_der), \ 262 .name_der = _label ## _name_der, \ 263 .name_size = sizeof(_label ## _name_der), \ 264 .label = #_label, \ 265 .label_size = sizeof(#_label) - 1, \ 266 } 267 268 static const struct supported_ecc_curve ec_curve_param[] = { 269 ECC_CURVE(TEE_ECC_CURVE_NIST_P192, 192, prime192v1), 270 ECC_CURVE(TEE_ECC_CURVE_NIST_P224, 224, secp224r1), 271 ECC_CURVE(TEE_ECC_CURVE_NIST_P256, 256, prime256v1), 272 ECC_CURVE(TEE_ECC_CURVE_NIST_P384, 384, secp384r1), 273 ECC_CURVE(TEE_ECC_CURVE_NIST_P521, 521, secp521r1), 274 }; 275 276 static const struct supported_ecc_curve *get_curve(void *attr, size_t size) 277 { 278 size_t idx = 0; 279 280 /* Weak: not a real DER parser: try by params then by named curve */ 281 for (idx = 0; idx < ARRAY_SIZE(ec_curve_param); idx++) { 282 const struct supported_ecc_curve *curve = ec_curve_param + idx; 283 284 if (size == curve->oid_size && 285 !TEE_MemCompare(attr, curve->oid_der, curve->oid_size)) 286 return curve; 287 288 if (size == curve->name_size && 289 !TEE_MemCompare(attr, curve->name_der, curve->name_size)) 290 return curve; 291 } 292 293 return NULL; 294 } 295 296 size_t ec_params2tee_keysize(void *ec_params, size_t size) 297 { 298 const struct supported_ecc_curve *curve = get_curve(ec_params, size); 299 300 if (!curve) 301 return 0; 302 303 return curve->key_size; 304 } 305 306 /* 307 * This function intentionally panics if the curve is not found. 308 * Use ec_params2tee_keysize() to check the curve is supported by 309 * the internal core API. 310 */ 311 uint32_t ec_params2tee_curve(void *ec_params, size_t size) 312 { 313 const struct supported_ecc_curve *curve = get_curve(ec_params, size); 314 315 assert(curve); 316 317 return curve->tee_id; 318 } 319 320 static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head, 321 struct obj_attrs **priv_head, 322 TEE_ObjectHandle tee_obj, 323 size_t tee_size) 324 { 325 void *x_ptr = NULL; 326 void *y_ptr = NULL; 327 uint8_t *ecpoint = NULL; 328 size_t x_size = 0; 329 size_t y_size = 0; 330 size_t psize = 0; 331 size_t qsize = 0; 332 size_t dersize = 0; 333 size_t poffset = 0; 334 size_t hsize = 0; 335 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 336 337 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE, 338 tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE); 339 if (rc) 340 goto out; 341 342 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X, 343 &x_ptr, &x_size); 344 if (rc) 345 goto out; 346 347 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y, 348 &y_ptr, &y_size); 349 if (rc) 350 goto x_cleanup; 351 352 psize = (tee_size + 7) / 8; 353 if (x_size > psize || y_size > psize) { 354 rc = PKCS11_CKR_ARGUMENTS_BAD; 355 goto y_cleanup; 356 } 357 358 qsize = 1 + 2 * psize; 359 if (qsize < 0x80) { 360 /* DER short definitive form up to 127 bytes */ 361 dersize = qsize + 2; 362 hsize = 2 /* der */ + 1 /* point compression */; 363 } else if (qsize < 0x100) { 364 /* DER long definitive form up to 255 bytes */ 365 dersize = qsize + 3; 366 hsize = 3 /* der */ + 1 /* point compression */; 367 } else { 368 EMSG("Too long DER value"); 369 rc = PKCS11_CKR_MECHANISM_PARAM_INVALID; 370 goto y_cleanup; 371 } 372 373 ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO); 374 if (!ecpoint) { 375 rc = PKCS11_CKR_DEVICE_MEMORY; 376 goto y_cleanup; 377 } 378 379 if (qsize < 0x80) { 380 /* DER encoding */ 381 ecpoint[0] = 0x04; 382 ecpoint[1] = qsize & 0x7f; 383 384 /* Only UNCOMPRESSED ECPOINT is currently supported */ 385 ecpoint[2] = 0x04; 386 } else if (qsize < 0x100) { 387 /* DER encoding */ 388 ecpoint[0] = 0x04; 389 ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */ 390 ecpoint[2] = qsize & 0xFF; 391 392 /* Only UNCOMPRESSED ECPOINT is currently supported */ 393 ecpoint[3] = 0x04; 394 } 395 396 poffset = 0; 397 if (x_size < psize) 398 poffset = psize - x_size; 399 TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size); 400 401 poffset = 0; 402 if (y_size < psize) 403 poffset = psize - y_size; 404 TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size); 405 406 /* 407 * Add EC_POINT on both private and public key objects as 408 * TEE_PopulateTransientObject requires public x/y values 409 * for TEE_TYPE_ECDSA_KEYPAIR. 410 */ 411 rc = add_attribute(priv_head, PKCS11_CKA_EC_POINT, ecpoint, dersize); 412 if (rc) 413 goto ecpoint_cleanup; 414 415 rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize); 416 417 ecpoint_cleanup: 418 TEE_Free(ecpoint); 419 y_cleanup: 420 TEE_Free(y_ptr); 421 x_cleanup: 422 TEE_Free(x_ptr); 423 out: 424 return rc; 425 } 426 427 enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params, 428 struct obj_attrs **pub_head, 429 struct obj_attrs **priv_head) 430 { 431 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 432 void *a_ptr = NULL; 433 uint32_t a_size = 0; 434 uint32_t tee_size = 0; 435 uint32_t tee_curve = 0; 436 TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL; 437 TEE_Attribute tee_key_attr[1] = { }; 438 TEE_Result res = TEE_ERROR_GENERIC; 439 440 if (!proc_params || !*pub_head || !*priv_head) 441 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 442 443 if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) || 444 remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) || 445 remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) { 446 EMSG("Unexpected attribute(s) found"); 447 trace_attributes("public-key", *pub_head); 448 trace_attributes("private-key", *priv_head); 449 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 450 } 451 452 if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS, 453 &a_ptr, &a_size) || !a_ptr) { 454 EMSG("No EC_PARAMS attribute found in public key"); 455 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 456 } 457 458 tee_size = ec_params2tee_keysize(a_ptr, a_size); 459 if (!tee_size) 460 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 461 462 tee_curve = ec_params2tee_curve(a_ptr, a_size); 463 464 TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0); 465 466 /* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */ 467 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size, 468 &tee_obj); 469 if (res) { 470 EMSG("Transient alloc failed with %#"PRIx32, res); 471 return tee2pkcs_error(res); 472 } 473 474 res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE); 475 if (res) { 476 rc = tee2pkcs_error(res); 477 goto out; 478 } 479 480 res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1); 481 if (res) { 482 rc = tee2pkcs_error(res); 483 goto out; 484 } 485 486 /* Private key needs the same EC_PARAMS as used by the public key */ 487 rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size); 488 if (rc) 489 goto out; 490 491 rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size); 492 493 out: 494 if (tee_obj != TEE_HANDLE_NULL) 495 TEE_CloseObject(tee_obj); 496 497 return rc; 498 } 499