LTP GCOV extension - code coverage report
Current view: directory - src/base - pdf-crypt.h
Test: libgnupdf.info
Date: 2011-08-25 Instrumented lines: 72
Code covered: 90.3 % Executed lines: 65

       1                 : /* -*- mode: C -*-
       2                 :  *
       3                 :  *       File:         pdf-crypt.c
       4                 :  *       Date:         Fri Feb 22 21:05:05 2008
       5                 :  *
       6                 :  *       GNU PDF Library - Header file for 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                 : #ifndef PDF_CRYPT_H
      27                 : #define PDF_CRYPT_H
      28                 : 
      29                 : #include <config.h>
      30                 : 
      31                 : #include <string.h>
      32                 : 
      33                 : #include <pdf-types.h>
      34                 : #include <pdf-error.h>
      35                 : #include <pdf-alloc.h>
      36                 : #include <pdf-crypt-c-aesv2.h>
      37                 : #include <pdf-crypt-c-v2.h>
      38                 : 
      39                 : /* BEGIN PUBLIC */
      40                 : 
      41                 : enum pdf_crypt_md_algo_e
      42                 : {
      43                 :     PDF_CRYPT_MD_MD5
      44                 : };
      45                 : 
      46                 : enum pdf_crypt_cipher_algo_e
      47                 : {
      48                 :   PDF_CRYPT_CIPHER_ALGO_AESV2,
      49                 :   PDF_CRYPT_CIPHER_ALGO_V2
      50                 : };
      51                 : 
      52                 : typedef struct pdf_crypt_cipher_s *pdf_crypt_cipher_t;
      53                 : typedef struct pdf_crypt_md_s *pdf_crypt_md_t;
      54                 : 
      55                 : /* END PUBLIC */
      56                 : 
      57                 : 
      58                 : struct pdf_crypt_cipher_algo_s
      59                 : {
      60                 :   pdf_status_t (*new) (void ** cipher);
      61                 : 
      62                 :   pdf_status_t (*setkey) (void * cipher, pdf_char_t *key, pdf_size_t size);
      63                 : 
      64                 :   pdf_status_t (*encrypt) (void * cipher,
      65                 :                            pdf_char_t *out, pdf_size_t out_size,
      66                 :                            pdf_char_t *in,  pdf_size_t in_size,
      67                 :                            pdf_size_t *result_size);
      68                 : 
      69                 :   pdf_status_t (*decrypt) (void * cipher,
      70                 :                            pdf_char_t *out, pdf_size_t out_size,
      71                 :                            pdf_char_t *in,  pdf_size_t in_sizem,
      72                 :                            pdf_size_t *result_size);
      73                 : 
      74                 :   pdf_status_t (*destroy) (void * cipher);
      75                 : };
      76                 : 
      77                 : typedef struct pdf_crypt_cipher_algo_s *pdf_crypt_cipher_algo_t;
      78                 : 
      79                 : struct pdf_crypt_cipher_s
      80                 : {
      81                 :   pdf_crypt_cipher_algo_t algo;
      82                 :   void * raw;
      83                 : };
      84                 : 
      85                 : struct pdf_crypt_md_s
      86                 : {
      87                 :   void * raw;
      88                 : };
      89                 : 
      90                 : 
      91                 : #if !defined HAVE_INLINE && !defined COMPILING_PDF_CRYPT
      92                 : 
      93                 : 
      94                 : pdf_status_t pdf_crypt_init (void);
      95                 : 
      96                 : 
      97                 : /* BEGIN PUBLIC */
      98                 : 
      99                 : pdf_status_t pdf_crypt_nonce (pdf_char_t * buffer, pdf_size_t size);
     100                 : 
     101                 : pdf_status_t pdf_crypt_cipher_new (enum pdf_crypt_cipher_algo_e algorithm,
     102                 :                                    pdf_crypt_cipher_t *cipher);
     103                 : 
     104                 : pdf_status_t pdf_crypt_cipher_setkey (pdf_crypt_cipher_t cipher,
     105                 :                                       pdf_char_t *key,
     106                 :                                       pdf_size_t size);
     107                 : 
     108                 : pdf_status_t pdf_crypt_cipher_encrypt (pdf_crypt_cipher_t cipher,
     109                 :                                        pdf_char_t *out,
     110                 :                                        pdf_size_t out_size,
     111                 :                                        pdf_char_t *in,
     112                 :                                        pdf_size_t in_size,
     113                 :                                        pdf_size_t *result_size);
     114                 : 
     115                 : pdf_status_t pdf_crypt_cipher_decrypt (pdf_crypt_cipher_t cipher,
     116                 :                                        pdf_char_t *out,
     117                 :                                        pdf_size_t out_size,
     118                 :                                        pdf_char_t *in,
     119                 :                                        pdf_size_t in_size,
     120                 :                                        pdf_size_t *result_size);
     121                 : 
     122                 : pdf_status_t pdf_crypt_cipher_destroy (pdf_crypt_cipher_t cipher);
     123                 : 
     124                 : 
     125                 : pdf_status_t pdf_crypt_md_new (enum pdf_crypt_md_algo_e algo, pdf_crypt_md_t *md);
     126                 : 
     127                 : pdf_status_t pdf_crypt_md_write (pdf_crypt_md_t md,
     128                 :                                  pdf_char_t *in,  pdf_size_t in_size);
     129                 : 
     130                 : pdf_status_t pdf_crypt_md_read (pdf_crypt_md_t md,
     131                 :                                 pdf_char_t *out, pdf_size_t out_size);
     132                 : 
     133                 : 
     134                 : pdf_status_t pdf_crypt_md_destroy (pdf_crypt_md_t hd);
     135                 : 
     136                 : 
     137                 : 
     138                 : /* END PUBLIC */
     139                 : 
     140                 : #else
     141                 : 
     142                 : #if defined COMPILING_PDF_CRYPT
     143                 : # define STATIC_INLINE
     144                 : #else
     145                 : # define STATIC_INLINE static inline
     146                 : #endif /* COMPILING_PDF_CRYPT */
     147                 : 
     148                 : 
     149                 : #include <gcrypt.h>
     150                 : 
     151                 : 
     152                 : STATIC_INLINE pdf_status_t
     153                 : pdf_crypt_init (void)
     154               0 : {
     155             749 :   gcry_check_version (GCRYPT_VERSION);
     156             749 :   return PDF_OK;
     157                 : }
     158                 : 
     159                 : 
     160                 : STATIC_INLINE pdf_status_t
     161                 : pdf_crypt_nonce (pdf_char_t * buffer, pdf_size_t size)
     162               1 : {
     163               1 :   gcry_create_nonce (buffer, size);
     164               1 :   return PDF_OK;
     165                 : }
     166                 : 
     167                 : 
     168                 : 
     169                 : STATIC_INLINE pdf_status_t
     170                 : pdf_crypt_cipher_new (enum pdf_crypt_cipher_algo_e algorithm,
     171                 :                       pdf_crypt_cipher_t *cipher)
     172              14 : {
     173                 :   pdf_status_t status;
     174                 :   pdf_crypt_cipher_algo_t cipher_algo;
     175                 :   
     176              54 :   *cipher = pdf_alloc (sizeof(struct pdf_crypt_cipher_s));
     177              54 :   cipher_algo = pdf_alloc (sizeof(struct pdf_crypt_cipher_algo_s));
     178                 : 
     179              54 :   switch (algorithm)
     180                 :     {
     181                 :     case PDF_CRYPT_CIPHER_ALGO_AESV2:
     182                 :       {
     183              29 :         cipher_algo->new = pdf_crypt_cipher_aesv2_new;
     184              29 :         cipher_algo->setkey = pdf_crypt_cipher_aesv2_setkey;
     185              29 :         cipher_algo->encrypt = pdf_crypt_cipher_aesv2_encrypt;
     186              29 :         cipher_algo->decrypt = pdf_crypt_cipher_aesv2_decrypt;
     187              29 :         cipher_algo->destroy = pdf_crypt_cipher_aesv2_destroy;
     188               9 :         break;
     189                 :       }
     190                 :     case PDF_CRYPT_CIPHER_ALGO_V2:
     191                 :       {
     192              25 :         cipher_algo->new = pdf_crypt_cipher_v2_new;
     193              25 :         cipher_algo->setkey = pdf_crypt_cipher_v2_setkey;
     194              25 :         cipher_algo->encrypt = pdf_crypt_cipher_v2_encrypt;
     195              25 :         cipher_algo->decrypt = pdf_crypt_cipher_v2_decrypt;
     196              25 :         cipher_algo->destroy = pdf_crypt_cipher_v2_destroy;
     197               5 :         break;
     198                 :       }
     199                 :     default:
     200                 :       {
     201                 :         /* Not reached, but makes stupid compilers happy */
     202               0 :         return PDF_ERROR;
     203                 :         break;
     204                 :       }
     205                 :     }
     206                 : 
     207              54 :   if (cipher_algo->new (&(*cipher)->raw) == PDF_OK)
     208                 :     {
     209              54 :       (*cipher)->algo = cipher_algo;
     210              54 :       status          = PDF_OK;
     211                 :     }
     212                 :   else
     213               0 :     status = PDF_ERROR;
     214                 :   
     215              54 :   return status;
     216                 : }
     217                 : 
     218                 : 
     219                 : STATIC_INLINE pdf_status_t
     220                 : pdf_crypt_cipher_setkey (pdf_crypt_cipher_t cipher,
     221                 :                          pdf_char_t *key, pdf_size_t size)
     222              10 : {
     223              50 :   return cipher->algo->setkey (cipher->raw, key, size);
     224                 : }
     225                 : 
     226                 : 
     227                 : STATIC_INLINE pdf_status_t
     228                 : pdf_crypt_cipher_encrypt (pdf_crypt_cipher_t cipher,
     229                 :                           pdf_char_t *out, pdf_size_t out_size,
     230                 :                           pdf_char_t *in,  pdf_size_t in_size,
     231                 :                           pdf_size_t *result_size)
     232               7 : {
     233              57 :   return cipher->algo->encrypt (cipher->raw, out, out_size, in, in_size, result_size);
     234                 : }
     235                 : 
     236                 : 
     237                 : STATIC_INLINE pdf_status_t
     238                 : pdf_crypt_cipher_decrypt (pdf_crypt_cipher_t cipher,
     239                 :                           pdf_char_t *out, pdf_size_t out_size,
     240                 :                           pdf_char_t *in,  pdf_size_t in_size,
     241                 :                           pdf_size_t *result_size)
     242               8 : {
     243              38 :   return cipher->algo->decrypt (cipher->raw, out, out_size, in, in_size, result_size);
     244                 : }
     245                 : 
     246                 : 
     247                 : STATIC_INLINE pdf_status_t
     248                 : pdf_crypt_cipher_destroy (pdf_crypt_cipher_t cipher)
     249              14 : {
     250                 :   pdf_status_t ret;
     251                 : 
     252              54 :   ret = cipher->algo->destroy (cipher->raw);
     253              54 :   pdf_dealloc (cipher->algo);
     254              54 :   pdf_dealloc (cipher);
     255              54 :   return ret;
     256                 : }
     257                 : 
     258                 : 
     259                 : /* Hashing functions */
     260                 : 
     261                 : 
     262                 : STATIC_INLINE pdf_status_t
     263                 : pdf_crypt_md_new (enum pdf_crypt_md_algo_e algo, pdf_crypt_md_t *_md)
     264               8 : {
     265                 :   pdf_crypt_md_t md;
     266                 :   gcry_md_hd_t * raw;
     267                 :   pdf_status_t ret;
     268                 :   
     269               8 :   md = pdf_alloc (sizeof(struct pdf_crypt_md_s));
     270                 : 
     271               8 :   if (algo == PDF_CRYPT_MD_MD5)
     272                 :     {
     273               7 :       raw = pdf_alloc (sizeof(gcry_md_hd_t));
     274                 : 
     275               7 :       if (gcry_md_open (raw, GCRY_MD_MD5, 0) == GPG_ERR_NO_ERROR)
     276                 :         {
     277               7 :           md->raw = raw;
     278               7 :           *_md = md;
     279               7 :           ret = PDF_OK;
     280                 :         }
     281                 :       else
     282                 :         {
     283               0 :           gcry_md_close (*raw);
     284               0 :           ret = PDF_ERROR;
     285                 :         }
     286                 :     }
     287                 :   else
     288                 :     {
     289               1 :       ret = PDF_EBADDATA;
     290                 :     }
     291                 : 
     292               8 :   return ret;
     293                 : }
     294                 : 
     295                 : 
     296                 : 
     297                 : STATIC_INLINE pdf_status_t
     298                 : pdf_crypt_md_write (pdf_crypt_md_t md,
     299                 :                     pdf_char_t *in,  pdf_size_t in_size)
     300               5 : {
     301               5 :   gcry_md_hd_t * gcry_md = md->raw;
     302               5 :   gcry_md_write (*gcry_md, in, in_size);
     303               5 :   return PDF_OK;
     304                 : }
     305                 : 
     306                 : 
     307                 : STATIC_INLINE pdf_status_t
     308                 : pdf_crypt_md_read (pdf_crypt_md_t md,
     309                 :                    pdf_char_t *out, pdf_size_t out_size)
     310               4 : {
     311               4 :   gcry_md_hd_t * gcry_md   = md->raw;
     312               4 :   pdf_size_t required_size = gcry_md_get_algo_dlen (GCRY_MD_MD5);
     313                 :   
     314               4 :   if (out_size < required_size)
     315               1 :     return PDF_EBADDATA;
     316                 :   
     317               3 :   if (gcry_md_final (*gcry_md) != GPG_ERR_NO_ERROR)
     318                 :     {
     319               0 :       return PDF_ERROR;
     320                 :     }
     321                 :   else
     322                 :     {
     323                 :       void * hash;
     324                 : 
     325               3 :       hash = gcry_md_read  (*gcry_md, GCRY_MD_MD5);
     326                 : 
     327               3 :       if (hash == NULL)
     328               0 :         return PDF_ERROR;
     329                 :       else
     330                 :         {
     331               3 :           memcpy (out, hash, required_size);
     332                 :         }
     333                 : 
     334               3 :       gcry_md_reset (*gcry_md);
     335               3 :       return PDF_OK;
     336                 :     }
     337                 : }
     338                 : 
     339                 : 
     340                 : 
     341                 : STATIC_INLINE pdf_status_t
     342                 : pdf_crypt_md_destroy (pdf_crypt_md_t md)
     343               7 : {
     344               7 :   pdf_dealloc (md->raw);
     345               7 :   pdf_dealloc (md);
     346               7 :   return PDF_OK;
     347                 : }
     348                 : 
     349                 : 
     350                 : 
     351                 : #endif /* COMPILING_PDF_CRYPT */
     352                 : #endif /* PDF_CRYPT_H */
     353                 : 
     354                 : /* End of pdf-crypt.h */

Generated by: LTP GCOV extension version 1.6