diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/server/src/drmcrypto.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/server/src/drmcrypto.c Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,687 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: DRM Crypto functionality +* +*/ + + + +/* + + DRMCrypto + -------------------------- + + SW module - ANSI C + +Location: - + +Filename: drmcrypto.c + +Document code: - + +/* ------------------------------------------------------------------------- */ + +/* 1 ABSTRACT + 1.1 Module type + 1.2 Functional description + 1.3 Notes + + 2 CONTENTS + + 3 GLOSSARY + + 4 REFERENCES + + 5 EXTERNAL RESOURCES + 5.1 Mandatory include files + 5.2 Library include files + 5.3 Interface include files + + 6 LOCAL DEFINITIONS + 6.1 Local include files + 6.2 Local constants + 6.3 Local macros + 6.3.1 dummy_message_type + 6.3.2 generate_connection_address + 6.4 Local data types + 6.5 Local data structures + 6.6 Local function prototypes + + 7 MODULE CODE + 7.1 DRMCrypto_Encrypt + 7.2 DRMCrypto_Decrypt + 7.3 DRMCrypto_EncryptRightsDb + 7.4 DRMCrypto_DecryptRightsVDb + 7.5 DRMCrypto_AddPadding + 7.6 DRMCrypto_RemovePadding + 7.7 DRMCrypto_GenerateKey + 7.8 DRMCrypto_GenerateIV + + + + + +*/ + + +/* 3 GLOSSARY + - +*/ + +/* 4 REFERENCES + + Specification reference + + DRM Engine Crypto Interface Specification + + + Design reference + + - + + Module test specification reference + + - +*/ +#ifndef C_DRMCRYPTO_CFILE +#define C_DRMCRYPTO_CFILE + +/* 5 EXTERNAL RESOURCES */ + +/* 5.1 Mandatory include files */ + +/* 5.2 Library include files */ + +/* 5.3 Interface include files */ +#include "drmcrypto.h" +#include "drmenv.h" /* for DRMEnv_GetRandom */ + +/* 6 LOCAL DEFINITIONS */ + +/* 6.1 Local include files */ + +#include "aes_if.h" + +/* 6.2 Local constants */ +#define KEYSEED_NUMBER_OF_INT32 4 +#define KEYSEED_LENGTH 16 +/* 6.3 Local macros */ + +/* 6.4 Local data types */ + +/* 6.5 Local data structures */ + +/* 6.6 Local function prototypes */ + +/* 7 MODULE CODE */ + + +/* ========================================================================= */ + +/* 7.1 */ + +/* Functional description + * + * Encrypt data using specified algorithm + * + * + * Parameters + * + * Cipher type + * + cType + * + * Pointer to encryption key + * + pszKey + * + * Encryption key length in bytes + * + iKeyLen + * + * Pointer to initializer vector of encryption + * + pszIV + * + * Pointer to data to be encrypted + * + pszIn + * + * Pointer to encrypted data. + * It can be same pointer as pszOut. + * + pszOut + * + * Length in bytes of content to be encrypted. + * + iInLen + * + * Cipher type(AES encryption modes). + * AES_MODE_CBC ... AES_MODE_ECB + * + uiParameters + * + * Return values + * + * If encryption is OK, return DRM_ENG_OK, + * otherwize DRM_ENG_ERROR. + */ + +/* ---------------------------------------------------------------------- */ + +#ifdef ENCRYPT_USED +uint8 DRMCrypto_Encrypt( + CipherType cType, + uint8* pszKey, + uint16 iKeyLen, + uint8* pszIV, + uint8* pszIn, + uint8* pszOut, + uint32 iInLen, + CipherParamType uiParameters ) + { + /* Data structures */ + + /* return code + */ + uint8 ret = 0; + + /* AES encryption mode + */ + uint8 iMode = 0; + + /* Code */ + + /* check parameter */ + if( !pszKey || !pszIV || !pszIn || !pszOut ) + { + return DRM_ENG_INVALID_PARAM; + } + + /* Convert uiParameters to inner interface type + */ + if( uiParameters == AES_MODE_CBC) + { + iMode = AES_CBC; + } + else if( uiParameters == AES_MODE_ECB) + { + iMode = AES_ECB; + } + else + { + DEBUG("Crypto Error: invalid uiParameters!") + return DRM_ENG_ERROR; + } + + if( cType == CIPHER_AES ) + { + ret = AESEncrypt( (uint32*)pszKey, (uint16)(iKeyLen*8), (uint32*)pszIV, + (uint32*)pszIn, (uint32*)pszOut, iInLen, iMode ); + if( ret==AES_CRYPTO_OK ) + { + return DRM_ENG_OK; + } + else if( ret == AES_CRYPTO_ERR_MEMORY ) + { + return DRM_ENG_MEM_ERROR; + } + else + { + DEBUGD("Crypto Error: AES Encryption Error ", ret) + return DRM_ENG_ERROR; + } + } + else + { + return DRM_ENG_ERROR; + } + } +#endif /* #ifdef ENCRYPT_USED */ + + +/* 7.2 */ + +/* Functional description + * + * Decrypt data using specified algorithm. + * + * + * Parameters + * + * Cipher type + * + cType + * + * Pointer to encryption key + * + pszKey + * + * Encryption key length in bytes + * + iKeyLen + * + * Pointer to initializer vector of encryption + * + pszIV + * + * Pointer to encrypted data which is to be decrypted + * + pszIn + * + * Pointer to decrypted content. + * It can be same pointer as pszOut. + * + pszOut + * + * Length in bytes of content to be decrypted. + * + iInLen + * + * Cipher type(AES encryption modes). + * AES_MODE_CBC ... AES_MODE_ECB + * + uiParameters + * + * Return values + * + * If decryption is OK, return DRM_ENG_OK, + * otherwize DRM_ENG_ERROR. + */ + +/* ---------------------------------------------------------------------- */ + + +uint8 DRMCrypto_Decrypt( + CipherType cType, + uint8* pszKey, + uint16 iKeyLen, + uint8* pszIV, + uint8* pszIn, + uint8* pszOut, + uint32 iInLen, + CipherParamType uiParameters ) + { + /* Data structures */ + + /* return code + */ + uint8 ret = 0; + + /* AES encryption mode + */ + uint8 iMode = 0; + + /* Aligned buffer for Key + */ + /* uint32* pKeyAligned=NULL; */ + + /* Aligned buffer for IV + */ + /* uint32* pIVAligned=NULL; */ + + /* Aligned buffer for Input data + */ + /* uint32* pInAligned=NULL; */ + + /* Byte stream pointer + */ + /* uint8* pBytes = NULL; */ + + /* Code */ + + /* check parameter */ + if( !pszKey || !pszIV || !pszIn || !pszOut ) + { + return DRM_ENG_INVALID_PARAM; + } + + /* Convert uiParameters to inner interface type + */ + if( uiParameters == AES_MODE_CBC) + { + iMode = AES_CBC; + } + else if( uiParameters == AES_MODE_ECB) + { + iMode = AES_ECB; + } + else + { + DEBUG("Crypto Error: invalid uiParameters !") + return DRM_ENG_ERROR; + } + + if( cType == CIPHER_AES ) + { + + ret = AESDecrypt( (uint32*)pszKey, (uint16)(iKeyLen*8), (uint32*)pszIV, + (uint32*)pszIn, (uint32*)pszOut, iInLen, iMode ); + + if( ret==AES_CRYPTO_OK ) + { + ret = DRM_ENG_OK; + } + else if( ret == AES_CRYPTO_ERR_MEMORY ) + { + ret = DRM_ENG_MEM_ERROR; + } + else + { + DEBUGD("Crypto Error: AES Decryption Error ", ret) + ret = DRM_ENG_ERROR; + } + } + else + { + ret = DRM_ENG_ERROR; + } + + return ret; + } + + +/* 7.5 */ + +/* Functional description + * + * Adds padding bytes at the end of data. + * + * + * Parameters + * + * Pointer to pointer to data. + * IN: points to data before adding padding bytes. + * OUT: points to data with added padding bytes. + * Memory used by input data will be freed inside this function. + * New memory will be allocated for output data. + * + ppData + * + * Pointer to data length in bytes + * IN: pointer to length of data with padding. + * OUT: points to length of data without padding. + * + pDataLen + * + * Cipher block size. + * Max 256 + * + CipBlockSize + * + * Specifies used padding method. + * PADDING_PKCS7 + * + uiPaddingMethod + * + * Return values + * + * If operation is OK, return DRM_ENG_OK, + * otherwize DRM_ENG_ERROR. + */ + +/* ---------------------------------------------------------------------- */ + + +uint8 DRMCrypto_AddPadding( + uint8** ppData, + uint32* pDataLen, + uint8 CipBlockSize, + PaddingMethodType uiPaddingMethod ) + { + /* Data structures */ + + /* Number of bytes to add to data + */ + uint8 padSize=0; + + /* Address of input data + */ + uint8 *pDataIn; + + /* Iterator + */ + uint16 i; + + /* return code */ + uint8 ret = DRM_ENG_OK; + + + /* Code */ + + /* check parameter */ + if( !ppData || !pDataLen ) + { + return DRM_ENG_INVALID_PARAM; + } + + if( uiPaddingMethod == PADDING_PKCS7) + { + /* calculate padding size + */ + padSize = (uint8)( CipBlockSize-( *pDataLen % CipBlockSize ) ); + + /* record input data address + */ + pDataIn = *ppData; + + /* allocate memory + */ + *ppData = (uint8*)DRM_BLOCK_ALLOC( *pDataLen+padSize ) ; + if( !(*ppData) ) + { + return DRM_ENG_MEM_ERROR; + } + + /* copy data + */ + DRM_BLOCK_COPY( *ppData, pDataIn, *pDataLen ); + + /* free memory for input data + */ + DRM_BLOCK_DEALLOC( pDataIn); + + /* add padding + */ + for( i=0; iCRYPTO_BLOCK_SIZE ) + { + DEBUG("Padding Size wrong!") + return DRM_ENG_ERROR; + } + + /* calculate new data length: + */ + *pDataLen = *pDataLen-padSize; + + return DRM_ENG_OK; + } + else + { + DEBUG( "Cypto Error: invalid uiPaddingMethod !" ) + ret = DRM_ENG_ERROR; + } + + return ret; + } + + +/* 7.8 */ + +/* Functional description + * + * Generates an initialization vector for cipher CBC mode. + * + * + * Parameters + * + * Lenght of the IV to be generated in bits. Must be a value between 1-16. + * + ivLen + * + * + * Pointer to pointer to the generated IV. + * + ppIV + * + * + * Return values + * + * If operation is OK, return DRM_ENG_OK, + * otherwize DRM_ENG_ERROR. + */ + +/* ---------------------------------------------------------------------- */ + +uint8 DRMCrypto_GenerateIV(uint32 ivLen, uint8 **ppIV) + { + /* Data structures */ + + /* return code */ + uint8 ret=DRM_ENG_OK; + + /* seed */ + uint8* pSeed=NULL; + + /* Code */ + + /* check parameter */ + if( ppIV == NULL || ivLen == 0 || ivLen > 16) + { + return DRM_ENG_INVALID_PARAM; + } + + /* allocate memory for IV */ + *ppIV = DRM_BLOCK_ALLOC( ivLen ); + + if( !(*ppIV) ) + { + return DRM_ENG_MEM_ERROR; + } + + /* generate random number as seed */ + pSeed = DRM_BLOCK_ALLOC( KEYSEED_LENGTH ); + if( !pSeed ) + { + ret = DRM_ENG_MEM_ERROR; + } + else + { + ret = DRMEnv_GetRandom( (uint32*)pSeed, KEYSEED_NUMBER_OF_INT32 ); + TRANSLATE_ERROR_CODE( ret ); + } + + /* generate IV by seed */ + if( ret == DRM_ENG_OK ) + { + /* Just copy the seed as IV. */ + DRM_BLOCK_COPY(*ppIV, pSeed, ivLen