LTP GCOV extension - code coverage report
Current view: directory - src/base - pdf-crypt-c-aesv2.c
Test: libgnupdf.info
Date: 2010-07-31 Instrumented lines: 70
Code covered: 82.9 % Executed lines: 58

       1                 : /* -*- mode: C -*-
       2                 :  *
       3                 :  *       File:         pdf-crypt.c
       4                 :  *       Date:         Fri Feb 22 21:05:05 2008
       5                 :  *
       6                 :  *       GNU PDF Library - AESV2 backend encryption module
       7                 :  *
       8                 :  */
       9                 : 
      10                 : /* Copyright (C) 2008 Free Software Foundation, Inc. */
      11                 : 
      12                 : /* This program is free software: you can redistribute it and/or modify
      13                 :  * it under the terms of the GNU General Public License as published by
      14                 :  * the Free Software Foundation, either version 3 of the License, or
      15                 :  * (at your option) any later version.
      16                 :  *
      17                 :  * This program is distributed in the hope that it will be useful,
      18                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :  * GNU General Public License for more details.
      21                 :  *
      22                 :  * You should have received a copy of the GNU General Public License
      23                 :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24                 :  */
      25                 : 
      26                 : #include <config.h>
      27                 : 
      28                 : #include <stdlib.h>
      29                 : #include <string.h>
      30                 : #include <gcrypt.h>
      31                 : 
      32                 : #include <pdf-alloc.h>
      33                 : #include <pdf-types.h>
      34                 : #include <pdf-error.h>
      35                 : #include <pdf-crypt-c-aesv2.h>
      36                 : #include <pdf-hash-helper.h>
      37                 : 
      38                 : #define AESV2_BLKSIZE 16        /* Size of a block in AES128 */
      39                 : 
      40                 : 
      41                 : struct aesv2_state_s
      42                 : {
      43                 :   gcry_cipher_hd_t cipher;
      44                 :   pdf_bool_t first_block;
      45                 : };
      46                 : 
      47                 : typedef struct aesv2_state_s * aesv2_state_t;
      48                 :   
      49                 : 
      50                 : /* Creation and destruction of aesv2 ciphers */
      51                 : 
      52                 : pdf_status_t
      53                 : pdf_crypt_cipher_aesv2_new (void ** out)
      54              12 : {
      55                 :   aesv2_state_t state;
      56                 : 
      57              12 :   state = pdf_alloc (sizeof(struct aesv2_state_s));
      58                 : 
      59              12 :   if (state != NULL)
      60                 :     {
      61                 :       gcry_error_t err;
      62                 : 
      63              12 :       err = gcry_cipher_open (&state->cipher, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
      64              12 :       state->first_block = PDF_TRUE;
      65                 :       
      66              12 :       if (err == GPG_ERR_NO_ERROR)
      67                 :         {
      68              12 :           *out = state;
      69              12 :           return PDF_OK;
      70                 :         }
      71                 :       else
      72                 :         {
      73               0 :           pdf_dealloc (state);
      74               0 :           return PDF_ERROR;
      75                 :         }
      76                 :     }
      77                 :   else
      78                 :     {
      79               0 :       pdf_dealloc (state);
      80               0 :       return PDF_ENOMEM;
      81                 :     }
      82                 : 
      83                 :   return PDF_OK;
      84                 : }
      85                 : 
      86                 : 
      87                 : 
      88                 : pdf_status_t
      89                 : pdf_crypt_cipher_aesv2_destroy (void * _state)
      90              12 : {
      91              12 :   aesv2_state_t state = _state;
      92              12 :   gcry_cipher_close (state->cipher);
      93              12 :   pdf_dealloc (state);
      94              12 :   return PDF_OK;
      95                 : }
      96                 : 
      97                 : 
      98                 : 
      99                 : /* Encryption and decryption functions */
     100                 : 
     101                 : pdf_status_t
     102                 : pdf_crypt_cipher_aesv2_setkey (void * _state,
     103                 :                                pdf_char_t *key, pdf_size_t size)
     104              10 : {
     105              10 :   aesv2_state_t state = _state;
     106                 :   
     107              10 :   if (gcry_cipher_setkey (state->cipher, key, size) == GPG_ERR_NO_ERROR)
     108                 :     {
     109               9 :       return PDF_OK;
     110                 :     }
     111                 :   else
     112                 :     {
     113               1 :       return PDF_EBADAESKEY;
     114                 :     }
     115                 : }
     116                 : 
     117                 : 
     118                 : 
     119                 : pdf_status_t
     120                 : pdf_crypt_cipher_aesv2_encrypt (void * _state,
     121                 :                                 pdf_char_t *out, pdf_size_t out_size,
     122                 :                                 pdf_char_t *in,  pdf_size_t in_size,
     123                 :                                 pdf_size_t *result_size)
     124              15 : {
     125              15 :   aesv2_state_t state = _state;
     126                 :   pdf_char_t * output;
     127                 :   pdf_size_t output_size;
     128                 :   pdf_char_t * input;
     129                 :   pdf_size_t input_size;
     130                 :   
     131              15 :   if (in_size < AESV2_BLKSIZE || in_size % AESV2_BLKSIZE != 0)
     132               0 :     return PDF_EBADDATA;
     133                 : 
     134              15 :   if (out_size < in_size)
     135               0 :     return PDF_EBADDATA;
     136                 : 
     137                 :   /* If we are at first block, then we have found the IV vector */
     138              15 :   if (state->first_block == PDF_TRUE)
     139                 :     {
     140               4 :       pdf_char_t * iv = in;
     141               4 :       gcry_cipher_setiv (state->cipher, iv, AESV2_BLKSIZE);
     142               4 :       input = in + AESV2_BLKSIZE;
     143               4 :       input_size = in_size - AESV2_BLKSIZE;
     144                 : 
     145               4 :       memcpy (out, iv, AESV2_BLKSIZE);
     146                 : 
     147               4 :       output = out + AESV2_BLKSIZE;
     148               4 :       output_size = out_size - AESV2_BLKSIZE;
     149                 : 
     150               4 :       state->first_block = PDF_FALSE;
     151                 :     }
     152                 :   else
     153                 :     {
     154              11 :       output = out;
     155              11 :       output_size = out_size;
     156              11 :       input = in;
     157              11 :       input_size = in_size;
     158                 :     }
     159                 : 
     160              15 :   if (gcry_cipher_encrypt (state->cipher, output, output_size, input, input_size) != GPG_ERR_NO_ERROR)
     161                 :     {
     162               0 :       return PDF_ERROR;
     163                 :     }
     164                 : 
     165              15 :   if (result_size != NULL)
     166               0 :     *result_size = in_size;
     167                 : 
     168              15 :   return PDF_OK;
     169                 : }
     170                 : 
     171                 : 
     172                 : 
     173                 : 
     174                 : pdf_status_t
     175                 : pdf_crypt_cipher_aesv2_decrypt (void * _state,
     176                 :                                 pdf_char_t *out, pdf_size_t out_size,
     177                 :                                 pdf_char_t *in,  pdf_size_t in_size,
     178                 :                                 pdf_size_t *result_size)
     179              10 : {
     180              10 :   aesv2_state_t state = _state;
     181                 :   pdf_char_t * output;
     182                 :   pdf_size_t output_size;
     183                 :   pdf_char_t * input;
     184                 :   pdf_size_t input_size;
     185                 :   
     186              10 :   if (in_size < AESV2_BLKSIZE || in_size % AESV2_BLKSIZE != 0)
     187               0 :     return PDF_EBADDATA;
     188                 : 
     189              10 :   if (out_size < in_size)
     190               0 :     return PDF_EBADDATA;
     191                 : 
     192                 :   /* If we are at first block, then we have found the IV vector */
     193              10 :   if (state->first_block == PDF_TRUE)
     194                 :     {
     195               4 :       pdf_char_t * iv = in;
     196               4 :       gcry_cipher_setiv (state->cipher, iv, AESV2_BLKSIZE);
     197               4 :       input = in + AESV2_BLKSIZE;
     198               4 :       input_size = in_size - AESV2_BLKSIZE;
     199                 : 
     200               4 :       memcpy (out, iv, AESV2_BLKSIZE);
     201                 : 
     202               4 :       output = out + AESV2_BLKSIZE;
     203               4 :       output_size = out_size - AESV2_BLKSIZE;
     204                 : 
     205               4 :       state->first_block = PDF_FALSE;
     206                 :     }
     207                 :   else
     208                 :     {
     209               6 :       output = out;
     210               6 :       output_size = out_size;
     211               6 :       input = in;
     212               6 :       input_size = in_size;
     213                 :     }
     214                 : 
     215              10 :   if (gcry_cipher_decrypt (state->cipher, output, output_size, input, input_size) != GPG_ERR_NO_ERROR)
     216                 :     {
     217               0 :       return PDF_ERROR;
     218                 :     }
     219                 : 
     220              10 :   if (result_size != NULL)
     221               0 :     *result_size = in_size;
     222                 : 
     223              10 :   return PDF_OK;
     224                 : }
     225                 : 
     226                 : 
     227                 : 
     228                 : 
     229                 : 
     230                 : /* End of pdf-crypt-c-aesv2.c */

Generated by: LTP GCOV extension version 1.6