1 /* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <stdlib.h> 28 #include <string.h> 29 30 #include <tee_api.h> 31 #include <utee_syscalls.h> 32 33 #include <assert.h> 34 35 #define TEE_USAGE_DEFAULT 0xffffffff 36 37 #define TEE_ATTR_BIT_VALUE (1 << 29) 38 #define TEE_ATTR_BIT_PROTECTED (1 << 28) 39 40 /* Data and Key Storage API - Generic Object Functions */ 41 void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 42 { 43 TEE_Result res; 44 45 res = utee_cryp_obj_get_info((uint32_t)object, objectInfo); 46 if (res != TEE_SUCCESS) 47 TEE_Panic(res); 48 } 49 50 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) 51 { 52 TEE_Result res; 53 res = utee_cryp_obj_restrict_usage((uint32_t)object, objectUsage); 54 55 if (res != TEE_SUCCESS) 56 TEE_Panic(0); 57 } 58 59 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 60 uint32_t attributeID, void *buffer, 61 uint32_t *size) 62 { 63 TEE_Result res; 64 TEE_ObjectInfo info; 65 66 res = utee_cryp_obj_get_info((uint32_t)object, &info); 67 if (res != TEE_SUCCESS) 68 TEE_Panic(0); 69 70 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) 71 TEE_Panic(0); 72 73 /* This function only supports reference attributes */ 74 if ((attributeID & TEE_ATTR_BIT_VALUE) != 0) 75 TEE_Panic(0); 76 77 res = 78 utee_cryp_obj_get_attr((uint32_t)object, attributeID, buffer, 79 size); 80 81 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && 82 res != TEE_ERROR_SHORT_BUFFER) 83 TEE_Panic(0); 84 85 return res; 86 } 87 88 TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object, 89 uint32_t attributeID, uint32_t *a, 90 uint32_t *b) 91 { 92 TEE_Result res; 93 TEE_ObjectInfo info; 94 uint32_t buf[2]; 95 size_t size = sizeof(buf); 96 97 res = utee_cryp_obj_get_info((uint32_t)object, &info); 98 if (res != TEE_SUCCESS) 99 TEE_Panic(0); 100 101 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) 102 TEE_Panic(0); 103 104 /* This function only supports value attributes */ 105 if ((attributeID & TEE_ATTR_BIT_VALUE) == 0) 106 TEE_Panic(0); 107 108 res = 109 utee_cryp_obj_get_attr((uint32_t)object, attributeID, buf, &size); 110 111 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && 112 res != TEE_ERROR_ACCESS_DENIED) 113 TEE_Panic(0); 114 115 if (size != sizeof(buf)) 116 TEE_Panic(0); 117 118 *a = buf[0]; 119 *b = buf[1]; 120 121 return res; 122 } 123 124 void TEE_CloseObject(TEE_ObjectHandle object) 125 { 126 TEE_Result res; 127 128 if (object == TEE_HANDLE_NULL) 129 return; 130 131 res = utee_cryp_obj_close((uint32_t)object); 132 if (res != TEE_SUCCESS) 133 TEE_Panic(0); 134 } 135 136 /* Data and Key Storage API - Transient Object Functions */ 137 138 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 139 uint32_t maxKeySize, 140 TEE_ObjectHandle *object) 141 { 142 TEE_Result res; 143 uint32_t obj; 144 145 res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 146 if (res == TEE_SUCCESS) 147 *object = (TEE_ObjectHandle) obj; 148 return res; 149 } 150 151 void TEE_FreeTransientObject(TEE_ObjectHandle object) 152 { 153 TEE_Result res; 154 TEE_ObjectInfo info; 155 156 if (object == TEE_HANDLE_NULL) 157 return; 158 159 res = utee_cryp_obj_get_info((uint32_t)object, &info); 160 if (res != TEE_SUCCESS) 161 TEE_Panic(0); 162 163 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 164 TEE_Panic(0); 165 166 res = utee_cryp_obj_close((uint32_t)object); 167 if (res != TEE_SUCCESS) 168 TEE_Panic(0); 169 } 170 171 void TEE_ResetTransientObject(TEE_ObjectHandle object) 172 { 173 TEE_Result res; 174 TEE_ObjectInfo info; 175 176 if (object == TEE_HANDLE_NULL) 177 return; 178 179 res = utee_cryp_obj_get_info((uint32_t)object, &info); 180 if (res != TEE_SUCCESS) 181 TEE_Panic(0); 182 183 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 184 TEE_Panic(0); 185 186 res = utee_cryp_obj_reset((uint32_t)object); 187 if (res != TEE_SUCCESS) 188 TEE_Panic(0); 189 } 190 191 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 192 TEE_Attribute *attrs, 193 uint32_t attrCount) 194 { 195 TEE_Result res; 196 TEE_ObjectInfo info; 197 198 res = utee_cryp_obj_get_info((uint32_t)object, &info); 199 if (res != TEE_SUCCESS) 200 TEE_Panic(0); 201 202 /* Must be a transient object */ 203 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 204 TEE_Panic(0); 205 206 /* Must not be initialized already */ 207 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 208 TEE_Panic(0); 209 210 res = utee_cryp_obj_populate((uint32_t)object, attrs, attrCount); 211 if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 212 TEE_Panic(res); 213 return res; 214 } 215 216 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID, 217 void *buffer, uint32_t length) 218 { 219 if (attr == NULL) 220 TEE_Panic(0); 221 if ((attributeID & TEE_ATTR_BIT_VALUE) != 0) 222 TEE_Panic(0); 223 attr->attributeID = attributeID; 224 attr->content.ref.buffer = buffer; 225 attr->content.ref.length = length; 226 } 227 228 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, 229 uint32_t a, uint32_t b) 230 { 231 if (attr == NULL) 232 TEE_Panic(0); 233 if ((attributeID & TEE_ATTR_BIT_VALUE) == 0) 234 TEE_Panic(0); 235 attr->attributeID = attributeID; 236 attr->content.value.a = a; 237 attr->content.value.b = b; 238 } 239 240 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, 241 TEE_ObjectHandle srcObject) 242 { 243 TEE_Result res; 244 TEE_ObjectInfo dst_info; 245 TEE_ObjectInfo src_info; 246 247 res = utee_cryp_obj_get_info((uint32_t)destObject, &dst_info); 248 if (res != TEE_SUCCESS) 249 TEE_Panic(0); 250 251 res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info); 252 if (res != TEE_SUCCESS) 253 TEE_Panic(0); 254 255 if ((src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) 256 TEE_Panic(0); 257 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 258 TEE_Panic(0); 259 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 260 TEE_Panic(0); 261 262 res = utee_cryp_obj_copy((uint32_t)destObject, (uint32_t)srcObject); 263 if (res != TEE_SUCCESS) 264 TEE_Panic(0); 265 } 266 267 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 268 TEE_Attribute *params, uint32_t paramCount) 269 { 270 TEE_Result res; 271 272 res = utee_cryp_obj_generate_key((uint32_t)object, keySize, 273 params, paramCount); 274 275 if (res != TEE_SUCCESS) 276 TEE_Panic(0); 277 278 return res; 279 } 280 281 /* Data and Key Storage API - Persistent Object Functions */ 282 283 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, void *objectID, 284 uint32_t objectIDLen, uint32_t flags, 285 TEE_ObjectHandle *object) 286 { 287 if (storageID != TEE_STORAGE_PRIVATE) 288 return TEE_ERROR_ITEM_NOT_FOUND; 289 290 if (objectID == NULL) 291 return TEE_ERROR_ITEM_NOT_FOUND; 292 293 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) 294 TEE_Panic(0); 295 296 if (object == NULL) 297 return TEE_ERROR_BAD_PARAMETERS; 298 299 return utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 300 object); 301 } 302 303 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, void *objectID, 304 uint32_t objectIDLen, uint32_t flags, 305 TEE_ObjectHandle attributes, 306 const void *initialData, 307 uint32_t initialDataLen, 308 TEE_ObjectHandle *object) 309 { 310 if (storageID != TEE_STORAGE_PRIVATE) 311 return TEE_ERROR_ITEM_NOT_FOUND; 312 313 if (objectID == NULL) 314 return TEE_ERROR_ITEM_NOT_FOUND; 315 316 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) 317 TEE_Panic(0); 318 319 if (object == NULL) 320 return TEE_ERROR_BAD_PARAMETERS; 321 322 return utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 323 attributes, initialData, initialDataLen, 324 object); 325 } 326 327 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 328 { 329 TEE_Result res; 330 331 if (object == TEE_HANDLE_NULL) 332 return; 333 334 res = utee_storage_obj_del(object); 335 336 if (res != TEE_SUCCESS) 337 TEE_Panic(0); 338 } 339 340 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 341 const void *newObjectID, 342 uint32_t newObjectIDLen) 343 { 344 TEE_Result res; 345 346 if (object == TEE_HANDLE_NULL) 347 return TEE_ERROR_ITEM_NOT_FOUND; 348 349 if (newObjectID == NULL) 350 return TEE_ERROR_BAD_PARAMETERS; 351 352 if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) 353 TEE_Panic(0); 354 355 res = utee_storage_obj_rename(object, newObjectID, newObjectIDLen); 356 357 if (res != TEE_SUCCESS && res != TEE_ERROR_ACCESS_CONFLICT) 358 TEE_Panic(0); 359 360 return res; 361 } 362 363 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 364 objectEnumerator) 365 { 366 TEE_Result res; 367 368 if (objectEnumerator == NULL) 369 return TEE_ERROR_BAD_PARAMETERS; 370 371 res = utee_storage_alloc_enum(objectEnumerator); 372 373 if (res != TEE_SUCCESS) 374 *objectEnumerator = TEE_HANDLE_NULL; 375 376 return res; 377 } 378 379 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 380 { 381 TEE_Result res; 382 383 if (objectEnumerator == TEE_HANDLE_NULL) 384 return; 385 386 res = utee_storage_free_enum(objectEnumerator); 387 388 if (res != TEE_SUCCESS) 389 TEE_Panic(0); 390 } 391 392 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 393 { 394 TEE_Result res; 395 396 if (objectEnumerator == TEE_HANDLE_NULL) 397 return; 398 399 res = utee_storage_reset_enum(objectEnumerator); 400 401 if (res != TEE_SUCCESS) 402 TEE_Panic(0); 403 } 404 405 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 406 objectEnumerator, 407 uint32_t storageID) 408 { 409 TEE_Result res; 410 411 if (storageID != TEE_STORAGE_PRIVATE) 412 return TEE_ERROR_ITEM_NOT_FOUND; 413 414 res = utee_storage_start_enum(objectEnumerator, storageID); 415 416 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND) 417 TEE_Panic(0); 418 419 return res; 420 } 421 422 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, 423 TEE_ObjectInfo *objectInfo, 424 void *objectID, uint32_t *objectIDLen) 425 { 426 TEE_Result res; 427 428 res = 429 utee_storage_next_enum(objectEnumerator, objectInfo, objectID, 430 objectIDLen); 431 432 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND) 433 TEE_Panic(0); 434 435 return res; 436 } 437 438 /* Data and Key Storage API - Data Stream Access Functions */ 439 440 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 441 uint32_t size, uint32_t *count) 442 { 443 TEE_Result res; 444 445 if (object == TEE_HANDLE_NULL) 446 TEE_Panic(0); 447 448 res = utee_storage_obj_read(object, buffer, size, count); 449 450 if (res != TEE_SUCCESS) 451 TEE_Panic(0); 452 453 return res; 454 } 455 456 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void *buffer, 457 uint32_t size) 458 { 459 TEE_Result res; 460 461 if (object == TEE_HANDLE_NULL) 462 TEE_Panic(0); 463 464 res = utee_storage_obj_write(object, buffer, size); 465 466 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE) 467 TEE_Panic(0); 468 469 return res; 470 } 471 472 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 473 { 474 TEE_Result res; 475 476 if (object == TEE_HANDLE_NULL) 477 TEE_Panic(0); 478 479 res = utee_storage_obj_trunc(object, size); 480 481 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE) 482 TEE_Panic(0); 483 484 return res; 485 } 486 487 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 488 TEE_Whence whence) 489 { 490 TEE_Result res; 491 TEE_ObjectInfo info; 492 493 if (object == TEE_HANDLE_NULL) 494 TEE_Panic(0); 495 496 res = utee_cryp_obj_get_info((uint32_t)object, &info); 497 if (res != TEE_SUCCESS) 498 TEE_Panic(0); 499 500 switch (whence) { 501 case TEE_DATA_SEEK_SET: 502 if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) 503 return TEE_ERROR_OVERFLOW; 504 break; 505 case TEE_DATA_SEEK_CUR: 506 if (offset > 0 && 507 ((uint32_t)offset + info.dataPosition > 508 TEE_DATA_MAX_POSITION || 509 (uint32_t)offset + info.dataPosition < 510 info.dataPosition)) 511 return TEE_ERROR_OVERFLOW; 512 break; 513 case TEE_DATA_SEEK_END: 514 if (offset > 0 && 515 ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION || 516 (uint32_t)offset + info.dataSize < info.dataSize)) 517 return TEE_ERROR_OVERFLOW; 518 break; 519 default: 520 TEE_Panic(0); 521 } 522 523 res = utee_storage_obj_seek(object, offset, whence); 524 525 if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) 526 TEE_Panic(0); 527 528 return res; 529 } 530