IDrm.cpp revision 8856c8b8777d0e0de11b2de863a336b001024e29
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "IDrm" 19#include <utils/Log.h> 20 21#include <binder/Parcel.h> 22#include <media/IDrm.h> 23#include <media/stagefright/MediaErrors.h> 24#include <media/stagefright/foundation/ADebug.h> 25#include <media/stagefright/foundation/AString.h> 26 27namespace android { 28 29enum { 30 INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION, 31 IS_CRYPTO_SUPPORTED, 32 CREATE_PLUGIN, 33 DESTROY_PLUGIN, 34 OPEN_SESSION, 35 CLOSE_SESSION, 36 GET_KEY_REQUEST, 37 PROVIDE_KEY_RESPONSE, 38 REMOVE_KEYS, 39 RESTORE_KEYS, 40 QUERY_KEY_STATUS, 41 GET_PROVISION_REQUEST, 42 PROVIDE_PROVISION_RESPONSE, 43 GET_SECURE_STOPS, 44 RELEASE_SECURE_STOPS, 45 GET_PROPERTY_STRING, 46 GET_PROPERTY_BYTE_ARRAY, 47 SET_PROPERTY_STRING, 48 SET_PROPERTY_BYTE_ARRAY, 49 SET_CIPHER_ALGORITHM, 50 SET_MAC_ALGORITHM, 51 ENCRYPT, 52 DECRYPT, 53 SIGN, 54 VERIFY 55}; 56 57struct BpDrm : public BpInterface<IDrm> { 58 BpDrm(const sp<IBinder> &impl) 59 : BpInterface<IDrm>(impl) { 60 } 61 62 virtual status_t initCheck() const { 63 Parcel data, reply; 64 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 65 remote()->transact(INIT_CHECK, data, &reply); 66 67 return reply.readInt32(); 68 } 69 70 virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) { 71 Parcel data, reply; 72 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 73 data.write(uuid, 16); 74 remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply); 75 76 return reply.readInt32() != 0; 77 } 78 79 virtual status_t createPlugin(const uint8_t uuid[16]) { 80 Parcel data, reply; 81 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 82 data.write(uuid, 16); 83 84 remote()->transact(CREATE_PLUGIN, data, &reply); 85 86 return reply.readInt32(); 87 } 88 89 virtual status_t destroyPlugin() { 90 Parcel data, reply; 91 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 92 remote()->transact(DESTROY_PLUGIN, data, &reply); 93 94 return reply.readInt32(); 95 } 96 97 virtual status_t openSession(Vector<uint8_t> &sessionId) { 98 Parcel data, reply; 99 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 100 101 remote()->transact(OPEN_SESSION, data, &reply); 102 readVector(reply, sessionId); 103 104 return reply.readInt32(); 105 } 106 107 virtual status_t closeSession(Vector<uint8_t> const &sessionId) { 108 Parcel data, reply; 109 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 110 111 writeVector(data, sessionId); 112 remote()->transact(CLOSE_SESSION, data, &reply); 113 114 return reply.readInt32(); 115 } 116 117 virtual status_t 118 getKeyRequest(Vector<uint8_t> const &sessionId, 119 Vector<uint8_t> const &initData, 120 String8 const &mimeType, DrmPlugin::KeyType keyType, 121 KeyedVector<String8, String8> const &optionalParameters, 122 Vector<uint8_t> &request, String8 &defaultUrl) { 123 Parcel data, reply; 124 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 125 126 writeVector(data, sessionId); 127 writeVector(data, initData); 128 data.writeString8(mimeType); 129 data.writeInt32((uint32_t)keyType); 130 131 data.writeInt32(optionalParameters.size()); 132 for (size_t i = 0; i < optionalParameters.size(); ++i) { 133 data.writeString8(optionalParameters.keyAt(i)); 134 data.writeString8(optionalParameters.valueAt(i)); 135 } 136 remote()->transact(GET_KEY_REQUEST, data, &reply); 137 138 readVector(reply, request); 139 defaultUrl = reply.readString8(); 140 141 return reply.readInt32(); 142 } 143 144 virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId, 145 Vector<uint8_t> const &response, 146 Vector<uint8_t> &keySetId) { 147 Parcel data, reply; 148 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 149 writeVector(data, sessionId); 150 writeVector(data, response); 151 remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply); 152 readVector(reply, keySetId); 153 154 return reply.readInt32(); 155 } 156 157 virtual status_t removeKeys(Vector<uint8_t> const &keySetId) { 158 Parcel data, reply; 159 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 160 161 writeVector(data, keySetId); 162 remote()->transact(REMOVE_KEYS, data, &reply); 163 164 return reply.readInt32(); 165 } 166 167 virtual status_t restoreKeys(Vector<uint8_t> const &sessionId, 168 Vector<uint8_t> const &keySetId) { 169 Parcel data, reply; 170 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 171 172 writeVector(data, sessionId); 173 writeVector(data, keySetId); 174 remote()->transact(RESTORE_KEYS, data, &reply); 175 176 return reply.readInt32(); 177 } 178 179 virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId, 180 KeyedVector<String8, String8> &infoMap) const { 181 Parcel data, reply; 182 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 183 184 writeVector(data, sessionId); 185 remote()->transact(QUERY_KEY_STATUS, data, &reply); 186 187 infoMap.clear(); 188 size_t count = reply.readInt32(); 189 for (size_t i = 0; i < count; i++) { 190 String8 key = reply.readString8(); 191 String8 value = reply.readString8(); 192 infoMap.add(key, value); 193 } 194 return reply.readInt32(); 195 } 196 197 virtual status_t getProvisionRequest(Vector<uint8_t> &request, 198 String8 &defaultUrl) { 199 Parcel data, reply; 200 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 201 202 remote()->transact(GET_PROVISION_REQUEST, data, &reply); 203 204 readVector(reply, request); 205 defaultUrl = reply.readString8(); 206 207 return reply.readInt32(); 208 } 209 210 virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) { 211 Parcel data, reply; 212 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 213 214 writeVector(data, response); 215 remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply); 216 217 return reply.readInt32(); 218 } 219 220 virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) { 221 Parcel data, reply; 222 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 223 224 remote()->transact(GET_SECURE_STOPS, data, &reply); 225 226 secureStops.clear(); 227 uint32_t count = reply.readInt32(); 228 for (size_t i = 0; i < count; i++) { 229 Vector<uint8_t> secureStop; 230 readVector(reply, secureStop); 231 secureStops.push_back(secureStop); 232 } 233 return reply.readInt32(); 234 } 235 236 virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) { 237 Parcel data, reply; 238 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 239 240 writeVector(data, ssRelease); 241 remote()->transact(RELEASE_SECURE_STOPS, data, &reply); 242 243 return reply.readInt32(); 244 } 245 246 virtual status_t getPropertyString(String8 const &name, String8 &value) const { 247 Parcel data, reply; 248 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 249 250 data.writeString8(name); 251 remote()->transact(GET_PROPERTY_STRING, data, &reply); 252 253 value = reply.readString8(); 254 return reply.readInt32(); 255 } 256 257 virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const { 258 Parcel data, reply; 259 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 260 261 data.writeString8(name); 262 remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply); 263 264 readVector(reply, value); 265 return reply.readInt32(); 266 } 267 268 virtual status_t setPropertyString(String8 const &name, String8 const &value) const { 269 Parcel data, reply; 270 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 271 272 data.writeString8(name); 273 data.writeString8(value); 274 remote()->transact(SET_PROPERTY_STRING, data, &reply); 275 276 return reply.readInt32(); 277 } 278 279 virtual status_t setPropertyByteArray(String8 const &name, 280 Vector<uint8_t> const &value) const { 281 Parcel data, reply; 282 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 283 284 data.writeString8(name); 285 writeVector(data, value); 286 remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply); 287 288 return reply.readInt32(); 289 } 290 291 292 virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId, 293 String8 const &algorithm) { 294 Parcel data, reply; 295 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 296 297 writeVector(data, sessionId); 298 data.writeString8(algorithm); 299 remote()->transact(SET_CIPHER_ALGORITHM, data, &reply); 300 return reply.readInt32(); 301 } 302 303 virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId, 304 String8 const &algorithm) { 305 Parcel data, reply; 306 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 307 308 writeVector(data, sessionId); 309 data.writeString8(algorithm); 310 remote()->transact(SET_MAC_ALGORITHM, data, &reply); 311 return reply.readInt32(); 312 } 313 314 virtual status_t encrypt(Vector<uint8_t> const &sessionId, 315 Vector<uint8_t> const &keyId, 316 Vector<uint8_t> const &input, 317 Vector<uint8_t> const &iv, 318 Vector<uint8_t> &output) { 319 Parcel data, reply; 320 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 321 322 writeVector(data, sessionId); 323 writeVector(data, keyId); 324 writeVector(data, input); 325 writeVector(data, iv); 326 327 remote()->transact(ENCRYPT, data, &reply); 328 readVector(reply, output); 329 330 return reply.readInt32(); 331 } 332 333 virtual status_t decrypt(Vector<uint8_t> const &sessionId, 334 Vector<uint8_t> const &keyId, 335 Vector<uint8_t> const &input, 336 Vector<uint8_t> const &iv, 337 Vector<uint8_t> &output) { 338 Parcel data, reply; 339 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 340 341 writeVector(data, sessionId); 342 writeVector(data, keyId); 343 writeVector(data, input); 344 writeVector(data, iv); 345 346 remote()->transact(DECRYPT, data, &reply); 347 readVector(reply, output); 348 349 return reply.readInt32(); 350 } 351 352 virtual status_t sign(Vector<uint8_t> const &sessionId, 353 Vector<uint8_t> const &keyId, 354 Vector<uint8_t> const &message, 355 Vector<uint8_t> &signature) { 356 Parcel data, reply; 357 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 358 359 writeVector(data, sessionId); 360 writeVector(data, keyId); 361 writeVector(data, message); 362 363 remote()->transact(SIGN, data, &reply); 364 readVector(reply, signature); 365 366 return reply.readInt32(); 367 } 368 369 virtual status_t verify(Vector<uint8_t> const &sessionId, 370 Vector<uint8_t> const &keyId, 371 Vector<uint8_t> const &message, 372 Vector<uint8_t> const &signature, 373 bool &match) { 374 Parcel data, reply; 375 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 376 377 writeVector(data, sessionId); 378 writeVector(data, keyId); 379 writeVector(data, message); 380 writeVector(data, signature); 381 382 remote()->transact(VERIFY, data, &reply); 383 match = (bool)reply.readInt32(); 384 return reply.readInt32(); 385 } 386 387private: 388 void readVector(Parcel &reply, Vector<uint8_t> &vector) const { 389 uint32_t size = reply.readInt32(); 390 vector.insertAt((size_t)0, size); 391 reply.read(vector.editArray(), size); 392 } 393 394 void writeVector(Parcel &data, Vector<uint8_t> const &vector) const { 395 data.writeInt32(vector.size()); 396 data.write(vector.array(), vector.size()); 397 } 398 399 DISALLOW_EVIL_CONSTRUCTORS(BpDrm); 400}; 401 402IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm"); 403 404//////////////////////////////////////////////////////////////////////////////// 405 406void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const { 407 uint32_t size = data.readInt32(); 408 vector.insertAt((size_t)0, size); 409 data.read(vector.editArray(), size); 410} 411 412void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const { 413 reply->writeInt32(vector.size()); 414 reply->write(vector.array(), vector.size()); 415} 416 417status_t BnDrm::onTransact( 418 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 419 switch (code) { 420 case INIT_CHECK: 421 { 422 CHECK_INTERFACE(IDrm, data, reply); 423 reply->writeInt32(initCheck()); 424 return OK; 425 } 426 427 case IS_CRYPTO_SUPPORTED: 428 { 429 CHECK_INTERFACE(IDrm, data, reply); 430 uint8_t uuid[16]; 431 data.read(uuid, sizeof(uuid)); 432 reply->writeInt32(isCryptoSchemeSupported(uuid)); 433 return OK; 434 } 435 436 case CREATE_PLUGIN: 437 { 438 CHECK_INTERFACE(IDrm, data, reply); 439 uint8_t uuid[16]; 440 data.read(uuid, sizeof(uuid)); 441 reply->writeInt32(createPlugin(uuid)); 442 return OK; 443 } 444 445 case DESTROY_PLUGIN: 446 { 447 CHECK_INTERFACE(IDrm, data, reply); 448 reply->writeInt32(destroyPlugin()); 449 return OK; 450 } 451 452 case OPEN_SESSION: 453 { 454 CHECK_INTERFACE(IDrm, data, reply); 455 Vector<uint8_t> sessionId; 456 status_t result = openSession(sessionId); 457 writeVector(reply, sessionId); 458 reply->writeInt32(result); 459 return OK; 460 } 461 462 case CLOSE_SESSION: 463 { 464 CHECK_INTERFACE(IDrm, data, reply); 465 Vector<uint8_t> sessionId; 466 readVector(data, sessionId); 467 reply->writeInt32(closeSession(sessionId)); 468 return OK; 469 } 470 471 case GET_KEY_REQUEST: 472 { 473 CHECK_INTERFACE(IDrm, data, reply); 474 Vector<uint8_t> sessionId, initData; 475 476 readVector(data, sessionId); 477 readVector(data, initData); 478 String8 mimeType = data.readString8(); 479 DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32(); 480 481 KeyedVector<String8, String8> optionalParameters; 482 uint32_t count = data.readInt32(); 483 for (size_t i = 0; i < count; ++i) { 484 String8 key, value; 485 key = data.readString8(); 486 value = data.readString8(); 487 optionalParameters.add(key, value); 488 } 489 490 Vector<uint8_t> request; 491 String8 defaultUrl; 492 493 status_t result = getKeyRequest(sessionId, initData, 494 mimeType, keyType, 495 optionalParameters, 496 request, defaultUrl); 497 writeVector(reply, request); 498 reply->writeString8(defaultUrl); 499 reply->writeInt32(result); 500 return OK; 501 } 502 503 case PROVIDE_KEY_RESPONSE: 504 { 505 CHECK_INTERFACE(IDrm, data, reply); 506 Vector<uint8_t> sessionId, response, keySetId; 507 readVector(data, sessionId); 508 readVector(data, response); 509 uint32_t result = provideKeyResponse(sessionId, response, keySetId); 510 writeVector(reply, keySetId); 511 reply->writeInt32(result); 512 return OK; 513 } 514 515 case REMOVE_KEYS: 516 { 517 CHECK_INTERFACE(IDrm, data, reply); 518 Vector<uint8_t> keySetId; 519 readVector(data, keySetId); 520 reply->writeInt32(removeKeys(keySetId)); 521 return OK; 522 } 523 524 case RESTORE_KEYS: 525 { 526 CHECK_INTERFACE(IDrm, data, reply); 527 Vector<uint8_t> sessionId, keySetId; 528 readVector(data, sessionId); 529 readVector(data, keySetId); 530 reply->writeInt32(restoreKeys(sessionId, keySetId)); 531 return OK; 532 } 533 534 case QUERY_KEY_STATUS: 535 { 536 CHECK_INTERFACE(IDrm, data, reply); 537 Vector<uint8_t> sessionId; 538 readVector(data, sessionId); 539 KeyedVector<String8, String8> infoMap; 540 status_t result = queryKeyStatus(sessionId, infoMap); 541 size_t count = infoMap.size(); 542 reply->writeInt32(count); 543 for (size_t i = 0; i < count; ++i) { 544 reply->writeString8(infoMap.keyAt(i)); 545 reply->writeString8(infoMap.valueAt(i)); 546 } 547 reply->writeInt32(result); 548 return OK; 549 } 550 551 case GET_PROVISION_REQUEST: 552 { 553 CHECK_INTERFACE(IDrm, data, reply); 554 Vector<uint8_t> request; 555 String8 defaultUrl; 556 status_t result = getProvisionRequest(request, defaultUrl); 557 writeVector(reply, request); 558 reply->writeString8(defaultUrl); 559 reply->writeInt32(result); 560 return OK; 561 } 562 563 case PROVIDE_PROVISION_RESPONSE: 564 { 565 CHECK_INTERFACE(IDrm, data, reply); 566 Vector<uint8_t> response; 567 readVector(data, response); 568 reply->writeInt32(provideProvisionResponse(response)); 569 return OK; 570 } 571 572 case GET_SECURE_STOPS: 573 { 574 CHECK_INTERFACE(IDrm, data, reply); 575 List<Vector<uint8_t> > secureStops; 576 status_t result = getSecureStops(secureStops); 577 size_t count = secureStops.size(); 578 reply->writeInt32(count); 579 List<Vector<uint8_t> >::iterator iter = secureStops.begin(); 580 while(iter != secureStops.end()) { 581 size_t size = iter->size(); 582 reply->writeInt32(size); 583 reply->write(iter->array(), iter->size()); 584 } 585 reply->writeInt32(result); 586 return OK; 587 } 588 589 case RELEASE_SECURE_STOPS: 590 { 591 CHECK_INTERFACE(IDrm, data, reply); 592 Vector<uint8_t> ssRelease; 593 readVector(data, ssRelease); 594 reply->writeInt32(releaseSecureStops(ssRelease)); 595 return OK; 596 } 597 598 case GET_PROPERTY_STRING: 599 { 600 CHECK_INTERFACE(IDrm, data, reply); 601 String8 name = data.readString8(); 602 String8 value; 603 status_t result = getPropertyString(name, value); 604 reply->writeString8(value); 605 reply->writeInt32(result); 606 return OK; 607 } 608 609 case GET_PROPERTY_BYTE_ARRAY: 610 { 611 CHECK_INTERFACE(IDrm, data, reply); 612 String8 name = data.readString8(); 613 Vector<uint8_t> value; 614 status_t result = getPropertyByteArray(name, value); 615 writeVector(reply, value); 616 reply->writeInt32(result); 617 return OK; 618 } 619 620 case SET_PROPERTY_STRING: 621 { 622 CHECK_INTERFACE(IDrm, data, reply); 623 String8 name = data.readString8(); 624 String8 value = data.readString8(); 625 reply->writeInt32(setPropertyString(name, value)); 626 return OK; 627 } 628 629 case SET_PROPERTY_BYTE_ARRAY: 630 { 631 CHECK_INTERFACE(IDrm, data, reply); 632 String8 name = data.readString8(); 633 Vector<uint8_t> value; 634 readVector(data, value); 635 reply->writeInt32(setPropertyByteArray(name, value)); 636 return OK; 637 } 638 639 case SET_CIPHER_ALGORITHM: 640 { 641 CHECK_INTERFACE(IDrm, data, reply); 642 Vector<uint8_t> sessionId; 643 readVector(data, sessionId); 644 String8 algorithm = data.readString8(); 645 reply->writeInt32(setCipherAlgorithm(sessionId, algorithm)); 646 return OK; 647 } 648 649 case SET_MAC_ALGORITHM: 650 { 651 CHECK_INTERFACE(IDrm, data, reply); 652 Vector<uint8_t> sessionId; 653 readVector(data, sessionId); 654 String8 algorithm = data.readString8(); 655 reply->writeInt32(setMacAlgorithm(sessionId, algorithm)); 656 return OK; 657 } 658 659 case ENCRYPT: 660 { 661 CHECK_INTERFACE(IDrm, data, reply); 662 Vector<uint8_t> sessionId, keyId, input, iv, output; 663 readVector(data, sessionId); 664 readVector(data, keyId); 665 readVector(data, input); 666 readVector(data, iv); 667 uint32_t result = encrypt(sessionId, keyId, input, iv, output); 668 writeVector(reply, output); 669 reply->writeInt32(result); 670 return OK; 671 } 672 673 case DECRYPT: 674 { 675 CHECK_INTERFACE(IDrm, data, reply); 676 Vector<uint8_t> sessionId, keyId, input, iv, output; 677 readVector(data, sessionId); 678 readVector(data, keyId); 679 readVector(data, input); 680 readVector(data, iv); 681 uint32_t result = decrypt(sessionId, keyId, input, iv, output); 682 writeVector(reply, output); 683 reply->writeInt32(result); 684 return OK; 685 } 686 687 case SIGN: 688 { 689 CHECK_INTERFACE(IDrm, data, reply); 690 Vector<uint8_t> sessionId, keyId, message, signature; 691 readVector(data, sessionId); 692 readVector(data, keyId); 693 readVector(data, message); 694 uint32_t result = sign(sessionId, keyId, message, signature); 695 writeVector(reply, signature); 696 reply->writeInt32(result); 697 return OK; 698 } 699 700 case VERIFY: 701 { 702 CHECK_INTERFACE(IDrm, data, reply); 703 Vector<uint8_t> sessionId, keyId, message, signature; 704 readVector(data, sessionId); 705 readVector(data, keyId); 706 readVector(data, message); 707 readVector(data, signature); 708 bool match; 709 uint32_t result = verify(sessionId, keyId, message, signature, match); 710 reply->writeInt32(match); 711 reply->writeInt32(result); 712 return OK; 713 } 714 715 default: 716 return BBinder::onTransact(code, data, reply, flags); 717 } 718} 719 720} // namespace android 721 722