omadrm/drmengine/server/src/drmcrypto.c
changeset 0 95b198f216e5
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  DRM Crypto functionality
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 /*
       
    21 
       
    22             DRMCrypto
       
    23             --------------------------
       
    24 
       
    25             SW module - ANSI C
       
    26 
       
    27 Location:           -
       
    28 
       
    29 Filename:           drmcrypto.c
       
    30 
       
    31 Document code:      -
       
    32 
       
    33 /* ------------------------------------------------------------------------- */
       
    34 
       
    35 /*  1    ABSTRACT
       
    36     1.1    Module type
       
    37     1.2    Functional description
       
    38     1.3    Notes
       
    39 
       
    40     2    CONTENTS
       
    41 
       
    42     3    GLOSSARY
       
    43 
       
    44     4    REFERENCES
       
    45 
       
    46     5    EXTERNAL RESOURCES
       
    47     5.1    Mandatory include files
       
    48     5.2    Library include files
       
    49     5.3    Interface include files
       
    50 
       
    51     6    LOCAL DEFINITIONS
       
    52     6.1    Local include files
       
    53     6.2    Local constants
       
    54     6.3    Local macros
       
    55     6.3.1    dummy_message_type
       
    56     6.3.2    generate_connection_address
       
    57     6.4    Local data types
       
    58     6.5    Local data structures
       
    59     6.6    Local function prototypes
       
    60 
       
    61     7    MODULE CODE
       
    62     7.1     DRMCrypto_Encrypt
       
    63 	7.2	    DRMCrypto_Decrypt
       
    64 	7.3		DRMCrypto_EncryptRightsDb
       
    65 	7.4		DRMCrypto_DecryptRightsVDb
       
    66 	7.5		DRMCrypto_AddPadding
       
    67 	7.6		DRMCrypto_RemovePadding
       
    68 	7.7		DRMCrypto_GenerateKey
       
    69 	7.8		DRMCrypto_GenerateIV
       
    70 
       
    71 
       
    72 
       
    73 
       
    74 
       
    75 */
       
    76 
       
    77 
       
    78 /*  3    GLOSSARY
       
    79 		 -
       
    80 */
       
    81 
       
    82 /*  4    REFERENCES
       
    83 
       
    84     Specification reference
       
    85 
       
    86     DRM Engine Crypto Interface Specification
       
    87 
       
    88 
       
    89     Design reference
       
    90 
       
    91     -
       
    92 
       
    93     Module test specification reference
       
    94 
       
    95     -
       
    96 */
       
    97 #ifndef C_DRMCRYPTO_CFILE
       
    98 #define C_DRMCRYPTO_CFILE
       
    99 
       
   100 /*  5    EXTERNAL RESOURCES */
       
   101 
       
   102 /*  5.1    Mandatory include files */
       
   103 
       
   104 /*  5.2    Library include files */
       
   105 
       
   106 /*  5.3    Interface include files */
       
   107 #include "drmcrypto.h"
       
   108 #include "drmenv.h" /* for DRMEnv_GetRandom */
       
   109 
       
   110 /*  6    LOCAL DEFINITIONS */
       
   111 
       
   112 /*  6.1    Local include files */
       
   113 
       
   114 #include "aes_if.h"
       
   115 
       
   116 /*  6.2    Local constants */
       
   117 #define	KEYSEED_NUMBER_OF_INT32		4
       
   118 #define KEYSEED_LENGTH				16
       
   119 /*  6.3    Local macros */
       
   120 
       
   121 /*  6.4    Local data types */
       
   122 
       
   123 /*  6.5    Local data structures */
       
   124 
       
   125 /*  6.6    Local function prototypes */
       
   126 
       
   127 /*  7    MODULE CODE */
       
   128 
       
   129 
       
   130 /* ========================================================================= */
       
   131 
       
   132 /*  7.1 */
       
   133 
       
   134 /* Functional description
       
   135  *
       
   136  * Encrypt data using specified algorithm
       
   137  *
       
   138  *
       
   139  * Parameters
       
   140  *
       
   141  * Cipher type
       
   142  *
       
   143  cType
       
   144  *
       
   145  * Pointer to encryption key
       
   146  *
       
   147  pszKey
       
   148  *
       
   149  * Encryption key length in bytes
       
   150  *
       
   151  iKeyLen
       
   152  *
       
   153  * Pointer to initializer vector of encryption
       
   154  *
       
   155  pszIV
       
   156  *
       
   157  * Pointer to data to be encrypted
       
   158  *
       
   159  pszIn
       
   160  *
       
   161  * Pointer to encrypted data.
       
   162  * It can be same pointer as pszOut.
       
   163  *
       
   164  pszOut
       
   165  *
       
   166  * Length in bytes of content to be encrypted.
       
   167  *
       
   168  iInLen
       
   169  *
       
   170  * Cipher type(AES encryption modes).
       
   171  *		AES_MODE_CBC ... AES_MODE_ECB
       
   172  *
       
   173  uiParameters
       
   174  *
       
   175  * Return values
       
   176  *
       
   177  * If encryption is OK, return DRM_ENG_OK, 
       
   178  * otherwize DRM_ENG_ERROR.
       
   179  */
       
   180 
       
   181 /* ---------------------------------------------------------------------- */
       
   182 
       
   183 #ifdef	ENCRYPT_USED
       
   184 uint8 DRMCrypto_Encrypt( 
       
   185 		  CipherType				cType, 
       
   186 		  uint8*					pszKey, 
       
   187 		  uint16					iKeyLen,
       
   188 		  uint8*					pszIV,
       
   189 		  uint8*					pszIn,
       
   190 		  uint8*					pszOut,
       
   191 		  uint32					iInLen, 
       
   192 		  CipherParamType			uiParameters	)
       
   193 	{
       
   194 	/* Data structures */
       
   195 
       
   196 	/* return code
       
   197 	 */
       
   198 	uint8 ret = 0;
       
   199 
       
   200 	/* AES encryption mode
       
   201 	 */
       
   202 	uint8 iMode = 0;
       
   203 
       
   204 	/*  Code  */
       
   205 
       
   206 	/* check parameter */
       
   207 	if( !pszKey || !pszIV || !pszIn || !pszOut )
       
   208 		{
       
   209 		return DRM_ENG_INVALID_PARAM;
       
   210 		}
       
   211 
       
   212 	/* Convert uiParameters to inner interface type
       
   213 	 */
       
   214 	if( uiParameters ==  AES_MODE_CBC)
       
   215 		{
       
   216 		iMode = AES_CBC;
       
   217 		}
       
   218 	else if( uiParameters ==  AES_MODE_ECB)
       
   219 		{
       
   220 		iMode = AES_ECB;
       
   221 		}
       
   222 	else 
       
   223 		{
       
   224 		DEBUG("Crypto Error: invalid uiParameters!")
       
   225 		return DRM_ENG_ERROR;
       
   226 		}
       
   227 
       
   228 	if( cType == CIPHER_AES )
       
   229 		{
       
   230 		ret = AESEncrypt( (uint32*)pszKey, (uint16)(iKeyLen*8), (uint32*)pszIV, 
       
   231 						  (uint32*)pszIn, (uint32*)pszOut, iInLen, iMode );
       
   232 		if( ret==AES_CRYPTO_OK ) 
       
   233 			{
       
   234 			return DRM_ENG_OK;
       
   235 			}
       
   236 		else if( ret == AES_CRYPTO_ERR_MEMORY )
       
   237 			{
       
   238 			return DRM_ENG_MEM_ERROR;
       
   239 			}
       
   240 		else 
       
   241 			{
       
   242 			DEBUGD("Crypto Error: AES Encryption Error ", ret)
       
   243 			return DRM_ENG_ERROR;
       
   244 			}
       
   245 		}
       
   246 	else
       
   247 		{
       
   248 		return DRM_ENG_ERROR;
       
   249 		}
       
   250 	}
       
   251 #endif /* #ifdef	ENCRYPT_USED */
       
   252 
       
   253 
       
   254 /*  7.2 */
       
   255 
       
   256 /* Functional description
       
   257  *
       
   258  * Decrypt data using specified algorithm.
       
   259  *
       
   260  *
       
   261  * Parameters
       
   262  *
       
   263  * Cipher type
       
   264  *
       
   265  cType
       
   266  *
       
   267  * Pointer to encryption key
       
   268  *
       
   269  pszKey
       
   270  *
       
   271  * Encryption key length in bytes
       
   272  *
       
   273  iKeyLen
       
   274  *
       
   275  * Pointer to initializer vector of encryption
       
   276  *
       
   277  pszIV
       
   278  *
       
   279  * Pointer to encrypted data which is to be decrypted
       
   280  *
       
   281  pszIn
       
   282  *
       
   283  * Pointer to decrypted content.
       
   284  * It can be same pointer as pszOut.
       
   285  *
       
   286  pszOut
       
   287  *
       
   288  * Length in bytes of content to be decrypted.
       
   289  *
       
   290  iInLen
       
   291  *
       
   292  * Cipher type(AES encryption modes).
       
   293  *		AES_MODE_CBC ... AES_MODE_ECB
       
   294  *
       
   295  uiParameters
       
   296  *
       
   297  * Return values
       
   298  *
       
   299  * If decryption is OK, return DRM_ENG_OK, 
       
   300  * otherwize DRM_ENG_ERROR.
       
   301  */
       
   302 
       
   303 /* ---------------------------------------------------------------------- */
       
   304 
       
   305 
       
   306 uint8 DRMCrypto_Decrypt( 
       
   307 		  CipherType				cType,
       
   308 		  uint8*					pszKey, 
       
   309           uint16					iKeyLen,
       
   310 		  uint8*					pszIV,
       
   311 		  uint8*					pszIn,
       
   312 		  uint8*					pszOut,
       
   313 		  uint32					iInLen,
       
   314 		  CipherParamType			uiParameters	)
       
   315 	{
       
   316 	/* Data structures */
       
   317 
       
   318 	/* return code
       
   319 	 */
       
   320 	uint8 ret = 0;
       
   321 
       
   322 	/* AES encryption mode
       
   323 	 */
       
   324 	uint8 iMode = 0;
       
   325 
       
   326 	/* Aligned buffer for Key
       
   327 	 */
       
   328 	/* uint32*			pKeyAligned=NULL; */
       
   329 
       
   330 	/* Aligned buffer for IV
       
   331 	 */
       
   332 	/* uint32*			pIVAligned=NULL; */
       
   333 
       
   334 	/* Aligned buffer for Input data
       
   335 	 */
       
   336 	/* uint32*			pInAligned=NULL; */
       
   337 
       
   338 	/* Byte stream pointer
       
   339 	 */
       
   340 	/* uint8* pBytes = NULL; */
       
   341 
       
   342 	/*  Code  */
       
   343 
       
   344 	/* check parameter */
       
   345 	if( !pszKey || !pszIV || !pszIn || !pszOut )
       
   346 		{
       
   347 		return DRM_ENG_INVALID_PARAM;
       
   348 		}
       
   349 
       
   350 	/* Convert uiParameters to inner interface type
       
   351 	 */
       
   352 	if( uiParameters ==  AES_MODE_CBC)
       
   353 		{
       
   354 		iMode = AES_CBC;
       
   355 		}
       
   356 	else if( uiParameters ==  AES_MODE_ECB)
       
   357 		{
       
   358 		iMode = AES_ECB;
       
   359 		}
       
   360 	else 
       
   361 		{
       
   362 		DEBUG("Crypto Error: invalid uiParameters !")
       
   363 		return DRM_ENG_ERROR;
       
   364 		}
       
   365 
       
   366 	if( cType == CIPHER_AES )
       
   367 		{
       
   368 			
       
   369 			ret = AESDecrypt( (uint32*)pszKey, (uint16)(iKeyLen*8), (uint32*)pszIV, 
       
   370 							  (uint32*)pszIn,  (uint32*)pszOut, iInLen, iMode );
       
   371 
       
   372 		if( ret==AES_CRYPTO_OK ) 
       
   373 			{
       
   374 			ret = DRM_ENG_OK;
       
   375 			}
       
   376 		else if( ret == AES_CRYPTO_ERR_MEMORY )
       
   377 			{
       
   378 			ret = DRM_ENG_MEM_ERROR;
       
   379 			}
       
   380 		else 
       
   381 			{
       
   382 			DEBUGD("Crypto Error: AES Decryption Error ", ret)
       
   383 			ret = DRM_ENG_ERROR;
       
   384 			}
       
   385 		}
       
   386 	else
       
   387 		{
       
   388 		ret = DRM_ENG_ERROR;
       
   389 		}
       
   390 
       
   391 	return ret;
       
   392 	}
       
   393 
       
   394 
       
   395 /*  7.5 */
       
   396 
       
   397 /* Functional description
       
   398  *
       
   399  * Adds padding bytes at the end of data.
       
   400  *
       
   401  *
       
   402  * Parameters
       
   403  *
       
   404  * Pointer to pointer to data.
       
   405  * IN: points to data before adding padding bytes.
       
   406  * OUT: points to data with added padding bytes.
       
   407  * Memory used by input data will be freed inside this function.
       
   408  * New memory will be allocated for output data.
       
   409  *
       
   410  ppData
       
   411  *
       
   412  * Pointer to data length in bytes
       
   413  * IN:  pointer to length of data with padding.
       
   414  * OUT: points to length of data without padding.
       
   415  *
       
   416  pDataLen
       
   417  *
       
   418  * Cipher block size. 
       
   419  * Max 256
       
   420  *
       
   421  CipBlockSize
       
   422  *
       
   423  * Specifies used padding method.
       
   424  *      PADDING_PKCS7
       
   425  *
       
   426  uiPaddingMethod
       
   427  *
       
   428  * Return values
       
   429  *
       
   430  * If operation is OK, return DRM_ENG_OK, 
       
   431  * otherwize DRM_ENG_ERROR.
       
   432  */
       
   433 
       
   434 /* ---------------------------------------------------------------------- */
       
   435 
       
   436 
       
   437 uint8 DRMCrypto_AddPadding(
       
   438 		  uint8**				ppData, 
       
   439 		  uint32*				pDataLen,
       
   440 		  uint8					CipBlockSize,
       
   441 		  PaddingMethodType		uiPaddingMethod	)
       
   442 	{
       
   443 	/* Data structures */
       
   444 
       
   445 	/* Number of bytes to add to data
       
   446 	 */
       
   447 	uint8	padSize=0;
       
   448 
       
   449 	/* Address of input data
       
   450 	 */
       
   451 	uint8	*pDataIn;
       
   452 
       
   453 	/* Iterator
       
   454 	 */
       
   455 	uint16	i;
       
   456 
       
   457 	/* return code */
       
   458 	uint8 ret = DRM_ENG_OK;
       
   459 
       
   460 
       
   461 	/*  Code  */
       
   462 
       
   463 	/* check parameter */
       
   464 	if( !ppData || !pDataLen )
       
   465 		{
       
   466 		return DRM_ENG_INVALID_PARAM;
       
   467 		}
       
   468 
       
   469 	if( uiPaddingMethod == PADDING_PKCS7)
       
   470 		{
       
   471 		/* calculate padding size
       
   472 		 */
       
   473 		padSize = (uint8)( CipBlockSize-( *pDataLen % CipBlockSize ) );
       
   474 	
       
   475 		/* record input data address
       
   476 		 */
       
   477 		pDataIn = *ppData;
       
   478 
       
   479 		/* allocate memory
       
   480 		 */
       
   481 		*ppData = (uint8*)DRM_BLOCK_ALLOC( *pDataLen+padSize ) ;
       
   482 		if( !(*ppData) )
       
   483 			{
       
   484 			return DRM_ENG_MEM_ERROR;
       
   485 			}
       
   486 
       
   487 		/* copy data
       
   488 		 */
       
   489 		DRM_BLOCK_COPY( *ppData, pDataIn, *pDataLen  );
       
   490 
       
   491 		/* free memory for input data
       
   492 		 */
       
   493 		DRM_BLOCK_DEALLOC( pDataIn);
       
   494 
       
   495 		/* add padding
       
   496 		 */
       
   497 		for( i=0; i<padSize; i++)
       
   498 			*( (uint8*)(*ppData) + *pDataLen +i) = padSize;
       
   499 
       
   500 		/* calculate new data length:
       
   501 		 */
       
   502 		*pDataLen = *pDataLen+padSize;
       
   503 
       
   504 		return	DRM_ENG_OK;
       
   505 		}
       
   506 	else
       
   507 		{
       
   508 		DEBUG( "Cypto Error: invalid uiPaddingMethod !" )
       
   509 		ret = DRM_ENG_ERROR;
       
   510 		}
       
   511 
       
   512 	return ret;
       
   513 	}
       
   514 
       
   515 
       
   516 
       
   517 /*  7.6 */
       
   518 
       
   519 /* Functional description
       
   520  *
       
   521  * Remove padding bytes from data.
       
   522  *
       
   523  *
       
   524  * Parameters
       
   525  *
       
   526  * Pointer to pointer to data(with padding bytes).
       
   527  * IN: points to data with padding bytes.
       
   528  * OUT: points to data without padding bytes.
       
   529  *
       
   530  ppData
       
   531  *
       
   532  * Pointer to data length in bytes
       
   533  * IN:  points to length of data with padding.
       
   534  * OUT: points to length of data without padding.
       
   535  *
       
   536  pDataLen
       
   537  *
       
   538  * Specifies used padding method.
       
   539  *      PADDING_PKCS7
       
   540  *
       
   541  uiPaddingMethod
       
   542  *
       
   543  * Return values
       
   544  *
       
   545  * If operation is OK, return DRM_ENG_OK, 
       
   546  * otherwize DRM_ENG_ERROR.
       
   547  */
       
   548 
       
   549 /* ---------------------------------------------------------------------- */
       
   550 
       
   551 
       
   552 uint8 DRMCrypto_RemovePadding(
       
   553 		  uint8**				ppData, 
       
   554 		  uint32*				pDataLen,
       
   555 		  PaddingMethodType		uiPaddingMethod	)
       
   556 	{
       
   557 	/* Data structures */
       
   558 
       
   559 	/* Number of bytes of padding data
       
   560 	 */
       
   561 	uint8	padSize=0;
       
   562 
       
   563 		/* return code */
       
   564 	uint8 ret = DRM_ENG_OK;
       
   565 
       
   566 	/*  Code  */
       
   567 
       
   568 	/* check parameter */
       
   569 	if( !ppData || !pDataLen )
       
   570 		{
       
   571 		return DRM_ENG_INVALID_PARAM;
       
   572 		}
       
   573 
       
   574 	if( uiPaddingMethod == PADDING_PKCS7)
       
   575 		{
       
   576 		/* calculate padding size
       
   577 		 * padding size is equal to last byte value of data
       
   578 		 */
       
   579 		padSize = *( (*ppData) + (*pDataLen) -1);
       
   580 
       
   581 		if( padSize<1 || padSize>CRYPTO_BLOCK_SIZE )
       
   582 			{
       
   583 			DEBUG("Padding Size wrong!")
       
   584 			return DRM_ENG_ERROR;
       
   585 			}
       
   586 
       
   587 		/* calculate new data length:
       
   588 		 */
       
   589 		*pDataLen = *pDataLen-padSize;
       
   590 
       
   591 		return	DRM_ENG_OK;
       
   592 		}
       
   593 	else
       
   594 		{
       
   595 		DEBUG( "Cypto Error: invalid uiPaddingMethod !" )
       
   596 		ret = DRM_ENG_ERROR;
       
   597 		}
       
   598 
       
   599 	return ret;
       
   600 	}
       
   601 
       
   602 
       
   603 /*  7.8 */
       
   604 
       
   605 /* Functional description
       
   606  *
       
   607  * Generates an initialization vector for cipher CBC mode. 
       
   608  *
       
   609  *
       
   610  * Parameters
       
   611  *
       
   612  * Lenght of the IV to be generated in bits. Must be a value between 1-16.
       
   613  *
       
   614  ivLen
       
   615  *
       
   616  *
       
   617  * Pointer to pointer to the generated IV.
       
   618  *
       
   619  ppIV
       
   620  *
       
   621  *
       
   622  * Return values
       
   623  *
       
   624  * If operation is OK, return DRM_ENG_OK, 
       
   625  * otherwize DRM_ENG_ERROR.
       
   626  */
       
   627 
       
   628 /* ---------------------------------------------------------------------- */
       
   629 
       
   630 uint8 DRMCrypto_GenerateIV(uint32 ivLen, uint8 **ppIV)
       
   631 	{
       
   632 	/* Data structures */
       
   633 
       
   634 	/* return code	 */
       
   635 	uint8	ret=DRM_ENG_OK;
       
   636 
       
   637 	/* seed */
       
   638 	uint8* pSeed=NULL;
       
   639 
       
   640 	/*  Code  */
       
   641 	
       
   642 	/* check parameter */
       
   643 	if( ppIV == NULL || ivLen == 0 || ivLen > 16)
       
   644 		{
       
   645 		return DRM_ENG_INVALID_PARAM;
       
   646 		}
       
   647 
       
   648 	/* allocate memory for IV */
       
   649 	*ppIV = DRM_BLOCK_ALLOC( ivLen );
       
   650 	
       
   651 	if( !(*ppIV) )
       
   652 		{
       
   653 		return DRM_ENG_MEM_ERROR;
       
   654 		}
       
   655 
       
   656 	/* generate random number as seed */
       
   657 	pSeed = DRM_BLOCK_ALLOC( KEYSEED_LENGTH );
       
   658 	if( !pSeed )
       
   659 		{
       
   660 		ret = DRM_ENG_MEM_ERROR;
       
   661 		}
       
   662 	else
       
   663 		{
       
   664 		ret = DRMEnv_GetRandom( (uint32*)pSeed, KEYSEED_NUMBER_OF_INT32 );
       
   665 		TRANSLATE_ERROR_CODE( ret );
       
   666 		}
       
   667 
       
   668 	/* generate IV by seed */
       
   669 	if( ret == DRM_ENG_OK )
       
   670 		{
       
   671 		/* Just copy the seed as IV. */
       
   672 		DRM_BLOCK_COPY(*ppIV, pSeed, ivLen<KEYSEED_LENGTH?ivLen:KEYSEED_LENGTH );
       
   673 		}
       
   674 	else /* free memory */
       
   675 		{
       
   676 		DRM_BLOCK_DEALLOC( *ppIV );
       
   677 		}
       
   678 
       
   679 	/* free memory */
       
   680 	DRM_BLOCK_DEALLOC( pSeed );
       
   681 
       
   682 	return ret;
       
   683 	}
       
   684 
       
   685 #endif /* #ifndef C_DRMCRYPTO_CFILE */
       
   686 /* End of File */
       
   687