| /* |
| * Copyright (C) 2007 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <util/crypto/DrmCrypto.h> |
| #include <ustring.h> |
| |
| using namespace ustl; |
| |
| void AesAgent::discardPaddingByte( unsigned char* decryptedBuf,unsigned long* decryptedBufLen)
|
| {
|
| if(!decryptedBuf)
|
| { |
| return; |
| } |
| |
| int i; |
| unsigned long tmpLen = *decryptedBufLen; |
|
|
| // Check whether the last several bytes are padding or not
|
| for ( i = 1; i < decryptedBuf[tmpLen - 1]; i++) |
| {
|
| if (decryptedBuf[tmpLen - 1 - i] != decryptedBuf[tmpLen - 1])
|
| break;
|
| } |
| |
| // They are padding bytes
|
| if (i == decryptedBuf[tmpLen - 1])
|
| { |
| *decryptedBufLen = tmpLen - i; |
| } |
|
|
| return;
|
| } |
| |
| int32_t AesAgent::decContent( unsigned char* iv, |
| const unsigned char* encData,
|
| unsigned long encLen,
|
| unsigned char* decData)
|
| { |
| if(AES_128_CBC == mode) |
| { |
| AES_KEY key; |
| AES_set_decrypt_key(AesKey,AES_KEY_BITS,&key); |
| |
| uint8_t *tmpBuf = new uint8_t[encLen]; |
| |
| AES_cbc_encrypt( encData, |
| tmpBuf, |
| encLen, |
| &key, |
| iv, |
| AES_DECRYPT); |
| |
| unsigned long tempLen = encLen; |
| discardPaddingByte(tmpBuf,&tempLen); |
| |
| memcpy(decData, tmpBuf, tempLen); |
| |
| delete []tmpBuf; |
| return encLen - tempLen; |
| } |
| else |
| { |
| return AES_DEC_FAILED; |
| } |
| } |
| |
| void Sha1Agent::computeHash( const unsigned char* inData,
|
| unsigned long inLen,
|
| unsigned char* outHash) const
|
| { |
| EVP_Digest(inData,inLen,outHash,NULL,EVP_sha1(),NULL); |
| return; |
| } |
| |
| void HmacSha1Agent::computeMac( const unsigned char* inData,
|
| unsigned long inLen,
|
| unsigned char* outData) const
|
| { |
| HMAC(EVP_sha1(),macKey,keyLen,inData,inLen,outData,NULL); |
| return; |
| } |
| |
| bool RsaAgent::signature( const unsigned char* rawData,
|
| unsigned long rawLen,
|
| unsigned char* sigData, |
| RsaAlg sigAlg)
|
| { |
| switch(sigAlg) |
| { |
| case RSA_PSS: |
| { |
| unsigned char mHash[SHA_DIGEST_LENGTH]; |
| Sha1Agent sha1; |
| sha1.computeHash(rawData,rawLen,mHash); |
| |
| unsigned char EM[rsaSize]; |
| if( 0 == RSA_padding_add_PKCS1_PSS( &rsaKey, |
| EM, |
| mHash, |
| EVP_sha1(), |
| SHA_DIGEST_LENGTH)) |
| { |
| return false; |
| } |
| |
| if(0 > RSA_private_encrypt( SHA_DIGEST_LENGTH, |
| EM, |
| sigData, |
| &rsaKey, |
| RSA_PKCS1_PADDING)) |
| { |
| return false; |
| } |
| else |
| { |
| return true;
|
| } |
| } |
| break; |
| case RSA_SHA1: |
| { |
| unsigned char mHash[SHA_DIGEST_LENGTH]; |
| Sha1Agent sha1; |
| sha1.computeHash(rawData,rawLen,mHash); |
| |
| if(0 != RSA_sign( NID_sha1WithRSA, |
| mHash, |
| SHA_DIGEST_LENGTH, |
| sigData, |
| &rsaSize, |
| &rsaKey)) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| break; |
| default: |
| return false; |
| } |
| |
| return false; |
| } |
| |
| bool RsaAgent::sigVerify( unsigned char* sigData, |
| unsigned long sigLen, |
| const unsigned char* rawData, |
| unsigned long rawLen, |
| RsaAlg sigAlg)
|
| { |
| if( sigAlg == RSA_PSS) |
| { |
| unsigned char decSigData[rsaSize]; |
| |
| if(0 > RSA_public_decrypt(sigLen, |
| sigData, |
| decSigData, |
| &rsaKey, |
| RSA_PKCS1_PADDING))
|
| { |
| return false; |
| } |
| else |
| { |
| unsigned char mHash[SHA_DIGEST_LENGTH]; |
| Sha1Agent sha1; |
| sha1.computeHash(rawData,rawLen,mHash); |
| |
| if( 0 == RSA_verify_PKCS1_PSS( &rsaKey, |
| mHash, |
| EVP_sha1(), |
| decSigData, |
| -1)) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| } |
| else if(sigAlg == RSA_SHA1) |
| { |
| unsigned char mHash[SHA_DIGEST_LENGTH]; |
| Sha1Agent sha1; |
| sha1.computeHash(rawData,rawLen,mHash); |
| |
| if(0 != RSA_verify( NID_sha1WithRSA, |
| mHash, |
| SHA_DIGEST_LENGTH, |
| sigData, |
| sigLen, |
| &rsaKey)) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| int RsaAgent::decrypt( const unsigned char* encData, |
| unsigned long encLen, |
| unsigned char* decData)
|
| { |
| return RSA_private_decrypt( encLen, |
| encData, |
| decData, |
| &rsaKey, |
| RSA_PKCS1_PADDING); |
| } |