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 <tee_internal_api_extensions.h> 11 #include <util.h> 12 13 #include "attributes.h" 14 #include "object.h" 15 #include "processing.h" 16 17 /* 18 * DER encoded EC parameters generated with script: 19 * ta/pkcs11/scripts/dump_ec_curve_params.sh 20 */ 21 22 static const uint8_t prime192v1_name_der[] = { 23 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 24 0x01, 0x01, 25 }; 26 27 static const uint8_t secp224r1_name_der[] = { 28 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x21, 29 }; 30 31 static const uint8_t prime256v1_name_der[] = { 32 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 33 0x01, 0x07, 34 }; 35 36 static const uint8_t secp384r1_name_der[] = { 37 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 38 }; 39 40 static const uint8_t secp521r1_name_der[] = { 41 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, 42 }; 43 44 static const uint8_t prime192v1_oid_der[] = { 45 0x30, 0x81, 0xc7, 0x02, 0x01, 0x01, 0x30, 0x24, 46 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 47 0x01, 0x02, 0x19, 0x00, 0xff, 0xff, 0xff, 0xff, 48 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 49 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 50 0xff, 0xff, 0xff, 0xff, 0x30, 0x4b, 0x04, 0x18, 51 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 52 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 54 0x04, 0x18, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c, 55 0x80, 0xe7, 0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24, 56 0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46, 57 0xb9, 0xb1, 0x03, 0x15, 0x00, 0x30, 0x45, 0xae, 58 0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57, 0x95, 59 0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21, 0x96, 60 0xd5, 0x04, 0x31, 0x04, 0x18, 0x8d, 0xa8, 0x0e, 61 0xb0, 0x30, 0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb, 62 0x43, 0xa1, 0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd, 63 0x82, 0xff, 0x10, 0x12, 0x07, 0x19, 0x2b, 0x95, 64 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed, 65 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 66 0x1e, 0x79, 0x48, 0x11, 0x02, 0x19, 0x00, 0xff, 67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 68 0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14, 69 0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31, 0x02, 70 0x01, 0x01, 71 }; 72 73 static const uint8_t secp224r1_oid_der[] = { 74 0x30, 0x81, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x28, 75 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 76 0x01, 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 77 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 78 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 80 0x30, 0x53, 0x04, 0x1c, 0xff, 0xff, 0xff, 0xff, 81 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 82 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 83 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 84 0x04, 0x1c, 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04, 85 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44, 86 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b, 87 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, 0x03, 0x15, 88 0x00, 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7, 89 0xfc, 0xdc, 0x45, 0xb5, 0x9f, 0xa3, 0xb9, 0xab, 90 0x8f, 0x6a, 0x94, 0x8b, 0xc5, 0x04, 0x39, 0x04, 91 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 92 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, 93 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6, 94 0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88, 95 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, 96 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 97 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34, 98 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 99 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 100 0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, 0x13, 101 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, 0x02, 102 0x01, 0x01, 103 }; 104 105 static const uint8_t prime256v1_oid_der[] = { 106 0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c, 107 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 108 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 109 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 112 0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20, 113 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 116 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 117 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 118 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 119 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 120 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 121 0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36, 122 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78, 123 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 124 0x90, 0x04, 0x41, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 125 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 126 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 127 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 128 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2, 129 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 130 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 131 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 132 0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 133 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 135 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 136 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, 0x02, 137 0x01, 0x01, 138 }; 139 140 static const uint8_t secp384r1_oid_der[] = { 141 0x30, 0x82, 0x01, 0x57, 0x02, 0x01, 0x01, 0x30, 142 0x3c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 143 0x01, 0x01, 0x02, 0x31, 0x00, 0xff, 0xff, 0xff, 144 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 147 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 148 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 149 0x00, 0xff, 0xff, 0xff, 0xff, 0x30, 0x7b, 0x04, 150 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 154 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 155 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 156 0xfc, 0x04, 0x30, 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 157 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3, 158 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 159 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50, 160 0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a, 161 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3, 162 0xec, 0x2a, 0xef, 0x03, 0x15, 0x00, 0xa3, 0x35, 163 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00, 164 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd, 165 0xac, 0x73, 0x04, 0x61, 0x04, 0xaa, 0x87, 0xca, 166 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7, 167 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b, 168 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41, 169 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2, 170 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e, 171 0x38, 0x72, 0x76, 0x0a, 0xb7, 0x36, 0x17, 0xde, 172 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 173 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 174 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 175 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 176 0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 177 0x7c, 0x90, 0xea, 0x0e, 0x5f, 0x02, 0x31, 0x00, 178 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 179 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 180 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 181 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf, 182 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a, 183 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73, 184 0x02, 0x01, 0x01, 185 }; 186 187 static const uint8_t secp521r1_oid_der[] = { 188 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 189 0x4d, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 190 0x01, 0x01, 0x02, 0x42, 0x01, 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, 0xff, 0xff, 197 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 198 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x81, 199 0x9f, 0x04, 0x42, 0x01, 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, 0xff, 0xff, 0xff, 0xff, 206 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 207 0xff, 0xff, 0xff, 0xff, 0xfc, 0x04, 0x42, 0x00, 208 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 209 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 210 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15, 211 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09, 212 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 213 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf, 214 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 215 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 216 0x00, 0x03, 0x15, 0x00, 0xd0, 0x9e, 0x88, 0x00, 217 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17, 218 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 219 0x04, 0x81, 0x85, 0x04, 0x00, 0xc6, 0x85, 0x8e, 220 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 221 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 222 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28, 223 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 224 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 225 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48, 226 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 227 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 228 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 229 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 230 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 231 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 232 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 233 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 234 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 235 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 236 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 237 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 238 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 239 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 240 0xff, 0xff, 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83, 241 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 242 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 243 0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 244 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01, 245 }; 246 247 struct supported_ecc_curve { 248 const uint8_t *oid_der; 249 size_t oid_size; 250 const uint8_t *name_der; 251 size_t name_size; 252 size_t key_size; 253 uint32_t tee_id; 254 const char *label; 255 size_t label_size; 256 }; 257 258 #define ECC_CURVE(_tee_id, _key_size, _label) \ 259 { \ 260 .tee_id = (_tee_id), \ 261 .key_size = (_key_size), \ 262 .oid_der = _label ## _oid_der, \ 263 .oid_size = sizeof(_label ## _oid_der), \ 264 .name_der = _label ## _name_der, \ 265 .name_size = sizeof(_label ## _name_der), \ 266 .label = #_label, \ 267 .label_size = sizeof(#_label) - 1, \ 268 } 269 270 static const struct supported_ecc_curve ec_curve_param[] = { 271 ECC_CURVE(TEE_ECC_CURVE_NIST_P192, 192, prime192v1), 272 ECC_CURVE(TEE_ECC_CURVE_NIST_P224, 224, secp224r1), 273 ECC_CURVE(TEE_ECC_CURVE_NIST_P256, 256, prime256v1), 274 ECC_CURVE(TEE_ECC_CURVE_NIST_P384, 384, secp384r1), 275 ECC_CURVE(TEE_ECC_CURVE_NIST_P521, 521, secp521r1), 276 }; 277 278 static const struct supported_ecc_curve *get_curve(void *attr, size_t size) 279 { 280 size_t idx = 0; 281 282 /* Weak: not a real DER parser: try by params then by named curve */ 283 for (idx = 0; idx < ARRAY_SIZE(ec_curve_param); idx++) { 284 const struct supported_ecc_curve *curve = ec_curve_param + idx; 285 286 if (size == curve->oid_size && 287 !TEE_MemCompare(attr, curve->oid_der, curve->oid_size)) 288 return curve; 289 290 if (size == curve->name_size && 291 !TEE_MemCompare(attr, curve->name_der, curve->name_size)) 292 return curve; 293 } 294 295 return NULL; 296 } 297 298 size_t ec_params2tee_keysize(void *ec_params, size_t size) 299 { 300 const struct supported_ecc_curve *curve = get_curve(ec_params, size); 301 302 if (!curve) 303 return 0; 304 305 return curve->key_size; 306 } 307 308 /* 309 * This function intentionally panics if the curve is not found. 310 * Use ec_params2tee_keysize() to check the curve is supported by 311 * the internal core API. 312 */ 313 uint32_t ec_params2tee_curve(void *ec_params, size_t size) 314 { 315 const struct supported_ecc_curve *curve = get_curve(ec_params, size); 316 317 assert(curve); 318 319 return curve->tee_id; 320 } 321 322 enum pkcs11_rc load_tee_ec_key_attrs(TEE_Attribute **tee_attrs, 323 size_t *tee_count, 324 struct pkcs11_object *obj) 325 { 326 TEE_Attribute *attrs = NULL; 327 size_t count = 0; 328 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 329 330 assert(get_key_type(obj->attributes) == PKCS11_CKK_EC); 331 332 switch (get_class(obj->attributes)) { 333 case PKCS11_CKO_PUBLIC_KEY: 334 attrs = TEE_Malloc(3 * sizeof(TEE_Attribute), 335 TEE_USER_MEM_HINT_NO_FILL_ZERO); 336 if (!attrs) 337 return PKCS11_CKR_DEVICE_MEMORY; 338 339 if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE, 340 obj, PKCS11_CKA_EC_PARAMS)) 341 count++; 342 343 if (pkcs2tee_load_attr(&attrs[count], 344 TEE_ATTR_ECC_PUBLIC_VALUE_X, 345 obj, PKCS11_CKA_EC_POINT)) 346 count++; 347 348 if (pkcs2tee_load_attr(&attrs[count], 349 TEE_ATTR_ECC_PUBLIC_VALUE_Y, 350 obj, PKCS11_CKA_EC_POINT)) 351 count++; 352 353 if (count == 3) 354 rc = PKCS11_CKR_OK; 355 356 break; 357 358 case PKCS11_CKO_PRIVATE_KEY: 359 attrs = TEE_Malloc(4 * sizeof(TEE_Attribute), 360 TEE_USER_MEM_HINT_NO_FILL_ZERO); 361 if (!attrs) 362 return PKCS11_CKR_DEVICE_MEMORY; 363 364 if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE, 365 obj, PKCS11_CKA_EC_PARAMS)) 366 count++; 367 368 if (pkcs2tee_load_attr(&attrs[count], 369 TEE_ATTR_ECC_PRIVATE_VALUE, 370 obj, PKCS11_CKA_VALUE)) 371 count++; 372 373 if (pkcs2tee_load_attr(&attrs[count], 374 TEE_ATTR_ECC_PUBLIC_VALUE_X, 375 obj, PKCS11_CKA_EC_POINT)) 376 count++; 377 378 if (pkcs2tee_load_attr(&attrs[count], 379 TEE_ATTR_ECC_PUBLIC_VALUE_Y, 380 obj, PKCS11_CKA_EC_POINT)) 381 count++; 382 383 if (count == 4) 384 rc = PKCS11_CKR_OK; 385 386 break; 387 388 default: 389 assert(0); 390 break; 391 } 392 393 if (rc == PKCS11_CKR_OK) { 394 *tee_attrs = attrs; 395 *tee_count = count; 396 } else { 397 TEE_Free(attrs); 398 } 399 400 return rc; 401 } 402 403 enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id, 404 struct pkcs11_attribute_head *proc_params, 405 struct pkcs11_object *obj) 406 { 407 switch (proc_params->id) { 408 case PKCS11_CKM_ECDSA: 409 case PKCS11_CKM_ECDSA_SHA1: 410 case PKCS11_CKM_ECDSA_SHA224: 411 case PKCS11_CKM_ECDSA_SHA256: 412 case PKCS11_CKM_ECDSA_SHA384: 413 case PKCS11_CKM_ECDSA_SHA512: 414 break; 415 default: 416 return PKCS11_CKR_GENERAL_ERROR; 417 } 418 419 /* 420 * TODO: Fixing this in a way to support also other EC curves would 421 * require OP-TEE to be updated for newer version of GlobalPlatform API 422 */ 423 switch (get_object_key_bit_size(obj)) { 424 case 192: 425 *tee_id = TEE_ALG_ECDSA_P192; 426 break; 427 case 224: 428 *tee_id = TEE_ALG_ECDSA_P224; 429 break; 430 case 256: 431 *tee_id = TEE_ALG_ECDSA_P256; 432 break; 433 case 384: 434 *tee_id = TEE_ALG_ECDSA_P384; 435 break; 436 case 521: 437 *tee_id = TEE_ALG_ECDSA_P521; 438 break; 439 default: 440 TEE_Panic(0); 441 break; 442 } 443 444 return PKCS11_CKR_OK; 445 } 446 447 static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head, 448 struct obj_attrs **priv_head, 449 TEE_ObjectHandle tee_obj, 450 size_t tee_size) 451 { 452 void *x_ptr = NULL; 453 void *y_ptr = NULL; 454 uint8_t *ecpoint = NULL; 455 size_t x_size = 0; 456 size_t y_size = 0; 457 size_t psize = 0; 458 size_t qsize = 0; 459 size_t dersize = 0; 460 size_t poffset = 0; 461 size_t hsize = 0; 462 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 463 464 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE, 465 tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE); 466 if (rc) 467 goto out; 468 469 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X, 470 &x_ptr, &x_size); 471 if (rc) 472 goto out; 473 474 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y, 475 &y_ptr, &y_size); 476 if (rc) 477 goto x_cleanup; 478 479 psize = (tee_size + 7) / 8; 480 if (x_size > psize || y_size > psize) { 481 rc = PKCS11_CKR_ARGUMENTS_BAD; 482 goto y_cleanup; 483 } 484 485 qsize = 1 + 2 * psize; 486 if (qsize < 0x80) { 487 /* DER short definitive form up to 127 bytes */ 488 dersize = qsize + 2; 489 hsize = 2 /* der */ + 1 /* point compression */; 490 } else if (qsize < 0x100) { 491 /* DER long definitive form up to 255 bytes */ 492 dersize = qsize + 3; 493 hsize = 3 /* der */ + 1 /* point compression */; 494 } else { 495 EMSG("Too long DER value"); 496 rc = PKCS11_CKR_MECHANISM_PARAM_INVALID; 497 goto y_cleanup; 498 } 499 500 ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO); 501 if (!ecpoint) { 502 rc = PKCS11_CKR_DEVICE_MEMORY; 503 goto y_cleanup; 504 } 505 506 if (qsize < 0x80) { 507 /* DER encoding */ 508 ecpoint[0] = 0x04; 509 ecpoint[1] = qsize & 0x7f; 510 511 /* Only UNCOMPRESSED ECPOINT is currently supported */ 512 ecpoint[2] = 0x04; 513 } else if (qsize < 0x100) { 514 /* DER encoding */ 515 ecpoint[0] = 0x04; 516 ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */ 517 ecpoint[2] = qsize & 0xFF; 518 519 /* Only UNCOMPRESSED ECPOINT is currently supported */ 520 ecpoint[3] = 0x04; 521 } 522 523 poffset = 0; 524 if (x_size < psize) 525 poffset = psize - x_size; 526 TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size); 527 528 poffset = 0; 529 if (y_size < psize) 530 poffset = psize - y_size; 531 TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size); 532 533 /* 534 * Add EC_POINT on both private and public key objects as 535 * TEE_PopulateTransientObject requires public x/y values 536 * for TEE_TYPE_ECDSA_KEYPAIR. 537 */ 538 rc = add_attribute(priv_head, PKCS11_CKA_EC_POINT, ecpoint, dersize); 539 if (rc) 540 goto ecpoint_cleanup; 541 542 rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize); 543 544 ecpoint_cleanup: 545 TEE_Free(ecpoint); 546 y_cleanup: 547 TEE_Free(y_ptr); 548 x_cleanup: 549 TEE_Free(x_ptr); 550 out: 551 return rc; 552 } 553 554 enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params, 555 struct obj_attrs **pub_head, 556 struct obj_attrs **priv_head) 557 { 558 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 559 void *a_ptr = NULL; 560 uint32_t a_size = 0; 561 uint32_t tee_size = 0; 562 uint32_t tee_curve = 0; 563 TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL; 564 TEE_Attribute tee_key_attr[1] = { }; 565 TEE_Result res = TEE_ERROR_GENERIC; 566 567 if (!proc_params || !*pub_head || !*priv_head) 568 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 569 570 if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) || 571 remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) || 572 remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) { 573 EMSG("Unexpected attribute(s) found"); 574 trace_attributes("public-key", *pub_head); 575 trace_attributes("private-key", *priv_head); 576 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 577 } 578 579 if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS, 580 &a_ptr, &a_size) || !a_ptr) { 581 EMSG("No EC_PARAMS attribute found in public key"); 582 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 583 } 584 585 tee_size = ec_params2tee_keysize(a_ptr, a_size); 586 if (!tee_size) 587 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 588 589 tee_curve = ec_params2tee_curve(a_ptr, a_size); 590 591 TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0); 592 593 /* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */ 594 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size, 595 &tee_obj); 596 if (res) { 597 EMSG("Transient alloc failed with %#"PRIx32, res); 598 return tee2pkcs_error(res); 599 } 600 601 res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE); 602 if (res) { 603 rc = tee2pkcs_error(res); 604 goto out; 605 } 606 607 res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1); 608 if (res) { 609 rc = tee2pkcs_error(res); 610 goto out; 611 } 612 613 /* Private key needs the same EC_PARAMS as used by the public key */ 614 rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size); 615 if (rc) 616 goto out; 617 618 rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size); 619 620 out: 621 if (tee_obj != TEE_HANDLE_NULL) 622 TEE_CloseObject(tee_obj); 623 624 return rc; 625 } 626 627 size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op) 628 { 629 TEE_OperationInfo info = { }; 630 631 TEE_GetOperationInfo(op, &info); 632 633 switch (info.algorithm) { 634 case TEE_ALG_ECDSA_P192: 635 return 24; 636 case TEE_ALG_ECDSA_P224: 637 return 28; 638 case TEE_ALG_ECDSA_P256: 639 return 32; 640 case TEE_ALG_ECDSA_P384: 641 return 48; 642 case TEE_ALG_ECDSA_P521: 643 return 66; 644 default: 645 DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm); 646 return 0; 647 } 648 } 649 650 enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params, 651 void **pub_data, size_t *pub_size) 652 { 653 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 654 struct serialargs args = { }; 655 uint32_t word = 0; 656 uint8_t byte = 0; 657 658 serialargs_init(&args, proc_params->data, proc_params->size); 659 660 /* Skip KDF */ 661 rc = serialargs_get_u32(&args, &word); 662 if (rc) 663 return rc; 664 665 /* Shared data size, shall be 0 */ 666 rc = serialargs_get_u32(&args, &word); 667 if (rc || word) 668 return rc; 669 670 /* Public data size and content */ 671 rc = serialargs_get_u32(&args, &word); 672 if (rc || !word) 673 return rc; 674 675 *pub_size = word; 676 677 rc = serialargs_get(&args, &byte, sizeof(uint8_t)); 678 if (rc) 679 return rc; 680 681 if (byte != 0x02 && byte != 0x03 && byte != 0x04) 682 return PKCS11_CKR_ARGUMENTS_BAD; 683 684 if (byte != 0x04) { 685 EMSG("DER compressed public key format not yet supported"); 686 return PKCS11_CKR_ARGUMENTS_BAD; 687 } 688 689 *pub_size -= sizeof(uint8_t); 690 691 if (*pub_size >= 0x80) { 692 EMSG("DER long definitive form not yet supported"); 693 return PKCS11_CKR_ARGUMENTS_BAD; 694 } 695 696 rc = serialargs_get_ptr(&args, pub_data, *pub_size); 697 if (rc) 698 return rc; 699 700 if (serialargs_remaining_bytes(&args)) 701 return PKCS11_CKR_ARGUMENTS_BAD; 702 703 return PKCS11_CKR_OK; 704 } 705 706 enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id, 707 struct pkcs11_attribute_head *proc_params, 708 struct pkcs11_object *obj) 709 { 710 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 711 struct serialargs args = { }; 712 uint32_t kdf = 0; 713 714 serialargs_init(&args, proc_params->data, proc_params->size); 715 716 rc = serialargs_get_u32(&args, &kdf); 717 if (rc) 718 return rc; 719 720 /* Remaining arguments are extracted by pkcs2tee_param_ecdh */ 721 if (kdf != PKCS11_CKD_NULL) { 722 DMSG("Only support CKD_NULL key derivation for ECDH"); 723 return PKCS11_CKR_MECHANISM_PARAM_INVALID; 724 } 725 726 switch (get_object_key_bit_size(obj)) { 727 case 192: 728 *tee_id = TEE_ALG_ECDH_P192; 729 break; 730 case 224: 731 *tee_id = TEE_ALG_ECDH_P224; 732 break; 733 case 256: 734 *tee_id = TEE_ALG_ECDH_P256; 735 break; 736 case 384: 737 *tee_id = TEE_ALG_ECDH_P384; 738 break; 739 case 521: 740 *tee_id = TEE_ALG_ECDH_P521; 741 break; 742 default: 743 TEE_Panic(0); 744 break; 745 } 746 747 return PKCS11_CKR_OK; 748 } 749