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