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 if (pkcs2tee_load_attr(&attrs[count], 392 TEE_ATTR_ECC_PUBLIC_VALUE_X, 393 obj, PKCS11_CKA_EC_POINT)) 394 count++; 395 396 if (pkcs2tee_load_attr(&attrs[count], 397 TEE_ATTR_ECC_PUBLIC_VALUE_Y, 398 obj, PKCS11_CKA_EC_POINT)) 399 count++; 400 401 if (count == 4) 402 rc = PKCS11_CKR_OK; 403 404 break; 405 406 default: 407 assert(0); 408 break; 409 } 410 411 if (rc == PKCS11_CKR_OK) { 412 *tee_attrs = attrs; 413 *tee_count = count; 414 } else { 415 TEE_Free(attrs); 416 } 417 418 return rc; 419 } 420 421 enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id, 422 struct pkcs11_attribute_head *proc_params, 423 struct pkcs11_object *obj) 424 { 425 switch (proc_params->id) { 426 case PKCS11_CKM_ECDSA: 427 case PKCS11_CKM_ECDSA_SHA1: 428 case PKCS11_CKM_ECDSA_SHA224: 429 case PKCS11_CKM_ECDSA_SHA256: 430 case PKCS11_CKM_ECDSA_SHA384: 431 case PKCS11_CKM_ECDSA_SHA512: 432 break; 433 default: 434 return PKCS11_CKR_GENERAL_ERROR; 435 } 436 437 /* 438 * TODO: Fixing this in a way to support also other EC curves would 439 * require OP-TEE to be updated for newer version of GlobalPlatform API 440 */ 441 switch (get_object_key_bit_size(obj)) { 442 case 192: 443 *tee_id = TEE_ALG_ECDSA_P192; 444 break; 445 case 224: 446 *tee_id = TEE_ALG_ECDSA_P224; 447 break; 448 case 256: 449 *tee_id = TEE_ALG_ECDSA_P256; 450 break; 451 case 384: 452 *tee_id = TEE_ALG_ECDSA_P384; 453 break; 454 case 521: 455 *tee_id = TEE_ALG_ECDSA_P521; 456 break; 457 default: 458 TEE_Panic(0); 459 break; 460 } 461 462 return PKCS11_CKR_OK; 463 } 464 465 static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head, 466 struct obj_attrs **priv_head, 467 TEE_ObjectHandle tee_obj, 468 size_t tee_size) 469 { 470 void *x_ptr = NULL; 471 void *y_ptr = NULL; 472 uint8_t *ecpoint = NULL; 473 size_t x_size = 0; 474 size_t y_size = 0; 475 size_t psize = 0; 476 size_t qsize = 0; 477 size_t dersize = 0; 478 size_t poffset = 0; 479 size_t hsize = 0; 480 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 481 482 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE, 483 tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE); 484 if (rc) 485 goto out; 486 487 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X, 488 &x_ptr, &x_size); 489 if (rc) 490 goto out; 491 492 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y, 493 &y_ptr, &y_size); 494 if (rc) 495 goto x_cleanup; 496 497 psize = (tee_size + 7) / 8; 498 if (x_size > psize || y_size > psize) { 499 rc = PKCS11_CKR_ARGUMENTS_BAD; 500 goto y_cleanup; 501 } 502 503 qsize = 1 + 2 * psize; 504 if (qsize < 0x80) { 505 /* DER short definitive form up to 127 bytes */ 506 dersize = qsize + 2; 507 hsize = 2 /* der */ + 1 /* point compression */; 508 } else if (qsize < 0x100) { 509 /* DER long definitive form up to 255 bytes */ 510 dersize = qsize + 3; 511 hsize = 3 /* der */ + 1 /* point compression */; 512 } else { 513 EMSG("Too long DER value"); 514 rc = PKCS11_CKR_MECHANISM_PARAM_INVALID; 515 goto y_cleanup; 516 } 517 518 ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO); 519 if (!ecpoint) { 520 rc = PKCS11_CKR_DEVICE_MEMORY; 521 goto y_cleanup; 522 } 523 524 if (qsize < 0x80) { 525 /* DER encoding */ 526 ecpoint[0] = 0x04; 527 ecpoint[1] = qsize & 0x7f; 528 529 /* Only UNCOMPRESSED ECPOINT is currently supported */ 530 ecpoint[2] = 0x04; 531 } else if (qsize < 0x100) { 532 /* DER encoding */ 533 ecpoint[0] = 0x04; 534 ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */ 535 ecpoint[2] = qsize & 0xFF; 536 537 /* Only UNCOMPRESSED ECPOINT is currently supported */ 538 ecpoint[3] = 0x04; 539 } 540 541 poffset = 0; 542 if (x_size < psize) 543 poffset = psize - x_size; 544 TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size); 545 546 poffset = 0; 547 if (y_size < psize) 548 poffset = psize - y_size; 549 TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size); 550 551 /* 552 * Add EC_POINT on both private and public key objects as 553 * TEE_PopulateTransientObject requires public x/y values 554 * for TEE_TYPE_ECDSA_KEYPAIR. 555 */ 556 rc = add_attribute(priv_head, PKCS11_CKA_EC_POINT, ecpoint, dersize); 557 if (rc) 558 goto ecpoint_cleanup; 559 560 rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize); 561 562 ecpoint_cleanup: 563 TEE_Free(ecpoint); 564 y_cleanup: 565 TEE_Free(y_ptr); 566 x_cleanup: 567 TEE_Free(x_ptr); 568 out: 569 return rc; 570 } 571 572 enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params, 573 struct obj_attrs **pub_head, 574 struct obj_attrs **priv_head) 575 { 576 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 577 void *a_ptr = NULL; 578 uint32_t a_size = 0; 579 uint32_t tee_size = 0; 580 uint32_t tee_curve = 0; 581 TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL; 582 TEE_Attribute tee_key_attr[1] = { }; 583 TEE_Result res = TEE_ERROR_GENERIC; 584 585 if (!proc_params || !*pub_head || !*priv_head) 586 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 587 588 if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) || 589 remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) || 590 remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) { 591 EMSG("Unexpected attribute(s) found"); 592 trace_attributes("public-key", *pub_head); 593 trace_attributes("private-key", *priv_head); 594 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 595 } 596 597 if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS, 598 &a_ptr, &a_size) || !a_ptr) { 599 EMSG("No EC_PARAMS attribute found in public key"); 600 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 601 } 602 603 tee_size = ec_params2tee_keysize(a_ptr, a_size); 604 if (!tee_size) 605 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 606 607 tee_curve = ec_params2tee_curve(a_ptr, a_size); 608 609 TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0); 610 611 /* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */ 612 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size, 613 &tee_obj); 614 if (res) { 615 EMSG("Transient alloc failed with %#"PRIx32, res); 616 return tee2pkcs_error(res); 617 } 618 619 res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE); 620 if (res) { 621 rc = tee2pkcs_error(res); 622 goto out; 623 } 624 625 res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1); 626 if (res) { 627 rc = tee2pkcs_error(res); 628 goto out; 629 } 630 631 /* Private key needs the same EC_PARAMS as used by the public key */ 632 rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size); 633 if (rc) 634 goto out; 635 636 rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size); 637 638 out: 639 if (tee_obj != TEE_HANDLE_NULL) 640 TEE_CloseObject(tee_obj); 641 642 return rc; 643 } 644 645 enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs, 646 size_t *tee_count, 647 struct pkcs11_object *obj) 648 { 649 TEE_Attribute *attrs = NULL; 650 size_t count = 0; 651 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 652 653 assert(get_key_type(obj->attributes) == PKCS11_CKK_EC_EDWARDS); 654 655 switch (get_class(obj->attributes)) { 656 case PKCS11_CKO_PUBLIC_KEY: 657 attrs = TEE_Malloc(sizeof(TEE_Attribute), 658 TEE_USER_MEM_HINT_NO_FILL_ZERO); 659 if (!attrs) 660 return PKCS11_CKR_DEVICE_MEMORY; 661 662 if (pkcs2tee_load_attr(&attrs[count], 663 TEE_ATTR_ED25519_PUBLIC_VALUE, 664 obj, PKCS11_CKA_EC_POINT)) 665 count++; 666 667 if (count == 1) 668 rc = PKCS11_CKR_OK; 669 670 break; 671 672 case PKCS11_CKO_PRIVATE_KEY: 673 attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), 674 TEE_USER_MEM_HINT_NO_FILL_ZERO); 675 if (!attrs) 676 return PKCS11_CKR_DEVICE_MEMORY; 677 678 if (pkcs2tee_load_attr(&attrs[count], 679 TEE_ATTR_ED25519_PRIVATE_VALUE, 680 obj, PKCS11_CKA_VALUE)) 681 count++; 682 683 if (pkcs2tee_load_attr(&attrs[count], 684 TEE_ATTR_ED25519_PUBLIC_VALUE, 685 obj, PKCS11_CKA_EC_POINT)) 686 count++; 687 688 if (count == 2) 689 rc = PKCS11_CKR_OK; 690 691 break; 692 693 default: 694 assert(0); 695 break; 696 } 697 698 if (rc == PKCS11_CKR_OK) { 699 *tee_attrs = attrs; 700 *tee_count = count; 701 } else { 702 TEE_Free(attrs); 703 } 704 705 return rc; 706 } 707 708 enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params, 709 struct obj_attrs **pub_head, 710 struct obj_attrs **priv_head) 711 { 712 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 713 void *a_ptr = NULL; 714 uint32_t a_size = 0; 715 uint32_t tee_size = 0; 716 TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL; 717 TEE_Result res = TEE_ERROR_GENERIC; 718 719 if (!proc_params || !*pub_head || !*priv_head) 720 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 721 722 if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) || 723 remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) || 724 remove_empty_attribute(priv_head, PKCS11_CKA_EC_POINT) || 725 remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) { 726 EMSG("Unexpected attribute(s) found"); 727 trace_attributes("public-key", *pub_head); 728 trace_attributes("private-key", *priv_head); 729 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 730 } 731 732 if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS, 733 &a_ptr, &a_size) || !a_ptr) { 734 EMSG("No EC_PARAMS attribute found in public key"); 735 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 736 } 737 738 tee_size = ec_params2tee_keysize(a_ptr, a_size); 739 if (!tee_size) 740 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; 741 742 res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size, 743 &tee_obj); 744 if (res) { 745 EMSG("Transient alloc failed with %#"PRIx32, res); 746 return tee2pkcs_error(res); 747 } 748 749 res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE); 750 if (res) { 751 rc = tee2pkcs_error(res); 752 goto out; 753 } 754 755 res = TEE_GenerateKey(tee_obj, tee_size, NULL, 0); 756 if (res) { 757 rc = tee2pkcs_error(res); 758 goto out; 759 } 760 761 /* Private key needs the same EC_PARAMS as used by the public key */ 762 rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size); 763 if (rc) 764 goto out; 765 766 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE, 767 tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE); 768 if (rc) 769 goto out; 770 771 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT, 772 tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE); 773 if (rc) 774 goto out; 775 776 rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT, 777 tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE); 778 779 out: 780 if (tee_obj != TEE_HANDLE_NULL) 781 TEE_CloseObject(tee_obj); 782 783 return rc; 784 } 785 786 enum pkcs11_rc 787 pkcs2tee_proc_params_eddsa(struct active_processing *proc, 788 struct pkcs11_attribute_head *proc_params) 789 { 790 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 791 uint32_t ctx_len = 0; 792 uint32_t flag = 0; 793 void *ctx_data = NULL; 794 struct serialargs args = { }; 795 struct eddsa_processing_ctx *ctx = NULL; 796 797 serialargs_init(&args, proc_params->data, proc_params->size); 798 799 rc = serialargs_get_u32(&args, &flag); 800 if (rc) 801 return rc; 802 803 rc = serialargs_get_u32(&args, &ctx_len); 804 if (rc) 805 return rc; 806 807 rc = serialargs_get_ptr(&args, &ctx_data, ctx_len); 808 if (rc) 809 return rc; 810 811 if (serialargs_remaining_bytes(&args)) 812 return PKCS11_CKR_ARGUMENTS_BAD; 813 814 proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len, 815 TEE_USER_MEM_HINT_NO_FILL_ZERO); 816 if (!proc->extra_ctx) 817 return PKCS11_CKR_DEVICE_MEMORY; 818 819 ctx = proc->extra_ctx; 820 ctx->ctx_len = ctx_len; 821 ctx->flag = flag; 822 TEE_MemMove(ctx->ctx, ctx_data, ctx_len); 823 824 return PKCS11_CKR_OK; 825 } 826 827 size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op) 828 { 829 TEE_OperationInfo info = { }; 830 831 TEE_GetOperationInfo(op, &info); 832 833 switch (info.algorithm) { 834 case TEE_ALG_ECDSA_P192: 835 return 24; 836 case TEE_ALG_ECDSA_P224: 837 return 28; 838 case TEE_ALG_ECDSA_P256: 839 return 32; 840 case TEE_ALG_ECDSA_P384: 841 return 48; 842 case TEE_ALG_ECDSA_P521: 843 return 66; 844 default: 845 DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm); 846 return 0; 847 } 848 } 849 850 enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params, 851 void **pub_data, size_t *pub_size) 852 { 853 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 854 struct serialargs args = { }; 855 uint32_t word = 0; 856 uint8_t byte = 0; 857 858 serialargs_init(&args, proc_params->data, proc_params->size); 859 860 /* Skip KDF */ 861 rc = serialargs_get_u32(&args, &word); 862 if (rc) 863 return rc; 864 865 /* Shared data size, shall be 0 */ 866 rc = serialargs_get_u32(&args, &word); 867 if (rc || word) 868 return rc; 869 870 /* Public data size and content */ 871 rc = serialargs_get_u32(&args, &word); 872 if (rc || !word) 873 return rc; 874 875 *pub_size = word; 876 877 rc = serialargs_get(&args, &byte, sizeof(uint8_t)); 878 if (rc) 879 return rc; 880 881 if (byte != 0x02 && byte != 0x03 && byte != 0x04) 882 return PKCS11_CKR_ARGUMENTS_BAD; 883 884 if (byte != 0x04) { 885 EMSG("DER compressed public key format not yet supported"); 886 return PKCS11_CKR_ARGUMENTS_BAD; 887 } 888 889 *pub_size -= sizeof(uint8_t); 890 891 if (*pub_size >= 0x80) { 892 EMSG("DER long definitive form not yet supported"); 893 return PKCS11_CKR_ARGUMENTS_BAD; 894 } 895 896 rc = serialargs_get_ptr(&args, pub_data, *pub_size); 897 if (rc) 898 return rc; 899 900 if (serialargs_remaining_bytes(&args)) 901 return PKCS11_CKR_ARGUMENTS_BAD; 902 903 return PKCS11_CKR_OK; 904 } 905 906 enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id, 907 struct pkcs11_attribute_head *proc_params, 908 struct pkcs11_object *obj) 909 { 910 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 911 struct serialargs args = { }; 912 uint32_t kdf = 0; 913 914 serialargs_init(&args, proc_params->data, proc_params->size); 915 916 rc = serialargs_get_u32(&args, &kdf); 917 if (rc) 918 return rc; 919 920 /* Remaining arguments are extracted by pkcs2tee_param_ecdh */ 921 if (kdf != PKCS11_CKD_NULL) { 922 DMSG("Only support CKD_NULL key derivation for ECDH"); 923 return PKCS11_CKR_MECHANISM_PARAM_INVALID; 924 } 925 926 switch (get_object_key_bit_size(obj)) { 927 case 192: 928 *tee_id = TEE_ALG_ECDH_P192; 929 break; 930 case 224: 931 *tee_id = TEE_ALG_ECDH_P224; 932 break; 933 case 256: 934 *tee_id = TEE_ALG_ECDH_P256; 935 break; 936 case 384: 937 *tee_id = TEE_ALG_ECDH_P384; 938 break; 939 case 521: 940 *tee_id = TEE_ALG_ECDH_P521; 941 break; 942 default: 943 TEE_Panic(0); 944 break; 945 } 946 947 return PKCS11_CKR_OK; 948 } 949