4141#include <sechash.h>
4242#elif defined(HAVE_GCRYPT )
4343#include <gcrypt.h>
44+ #elif defined(HAVE_OPENSSL_CRYPTO )
45+ #include <openssl/evp.h>
46+ #include <openssl/opensslv.h>
4447#else
4548#error "No crypto library available!"
4649#endif
4750
51+ /*
52+ * Compatibility shim for OpenSSL < 1.1.0, which used EVP_MD_CTX_create() and
53+ * EVP_MD_CTX_destroy() instead of the EVP_MD_CTX_new() / EVP_MD_CTX_free()
54+ * names introduced in 1.1.0.
55+ */
56+ #if defined(HAVE_OPENSSL_CRYPTO ) && OPENSSL_VERSION_NUMBER < 0x10100000L
57+ # define EVP_MD_CTX_new () EVP_MD_CTX_create()
58+ # define EVP_MD_CTX_free (c ) EVP_MD_CTX_destroy(c)
59+ #endif
60+
4861#if defined(HAVE_NSS3 )
4962static int crapi_alg_t_to_lib_arg (crapi_alg_t alg )
5063{
@@ -95,8 +108,72 @@ static int crapi_alg_t_to_lib_arg(crapi_alg_t alg)
95108 return -1 ;
96109 }
97110}
111+ #elif defined(HAVE_OPENSSL_CRYPTO )
112+ static const EVP_MD * crapi_alg_t_to_evp_md (crapi_alg_t alg )
113+ {
114+ switch (alg ) {
115+ #ifdef OPENSCAP_ENABLE_MD5
116+ case CRAPI_DIGEST_MD5 :
117+ return EVP_md5 ();
118+ #endif
119+ #ifdef OPENSCAP_ENABLE_SHA1
120+ case CRAPI_DIGEST_SHA1 :
121+ return EVP_sha1 ();
122+ #endif
123+ case CRAPI_DIGEST_SHA224 :
124+ return EVP_sha224 ();
125+ case CRAPI_DIGEST_SHA256 :
126+ return EVP_sha256 ();
127+ case CRAPI_DIGEST_SHA384 :
128+ return EVP_sha384 ();
129+ case CRAPI_DIGEST_SHA512 :
130+ return EVP_sha512 ();
131+ default :
132+ return NULL ;
133+ }
134+ }
98135#endif
99136
137+ #if defined(HAVE_OPENSSL_CRYPTO )
138+ /* Read fd and compute its digest using the streaming EVP API. */
139+ static int crapi_digest_fd_stream (int fd , const EVP_MD * evp_md , void * dst , size_t * size )
140+ {
141+ uint8_t buf [CRAPI_IO_BUFSZ ];
142+ ssize_t ret ;
143+
144+ EVP_MD_CTX * ctx = EVP_MD_CTX_new ();
145+ if (ctx == NULL )
146+ return -1 ;
147+ if (EVP_DigestInit_ex (ctx , evp_md , NULL ) != 1 ) {
148+ EVP_MD_CTX_free (ctx );
149+ return -1 ;
150+ }
151+ while ((ret = read (fd , buf , sizeof buf )) == sizeof buf )
152+ EVP_DigestUpdate (ctx , (const void * )buf , sizeof buf );
153+ switch (ret ) {
154+ case 0 :
155+ break ;
156+ case -1 :
157+ EVP_MD_CTX_free (ctx );
158+ return -1 ;
159+ default :
160+ if (ret <= 0 ) {
161+ EVP_MD_CTX_free (ctx );
162+ return -1 ;
163+ }
164+ EVP_DigestUpdate (ctx , (const void * )buf , (size_t )ret );
165+ }
166+ unsigned int md_len = (unsigned int )* size ;
167+ if (EVP_DigestFinal_ex (ctx , (unsigned char * )dst , & md_len ) != 1 ) {
168+ EVP_MD_CTX_free (ctx );
169+ return -1 ;
170+ }
171+ * size = (size_t )md_len ;
172+ EVP_MD_CTX_free (ctx );
173+ return 0 ;
174+ }
175+ #endif /* HAVE_OPENSSL_CRYPTO */
176+
100177int crapi_digest_fd (int fd , crapi_alg_t alg , void * dst , size_t * size )
101178{
102179 struct stat st ;
@@ -107,6 +184,22 @@ int crapi_digest_fd(int fd, crapi_alg_t alg, void *dst, size_t *size)
107184 errno = EFAULT ;
108185 return -1 ;
109186 }
187+
188+ /*
189+ * Resolve the algorithm and verify the output buffer is large enough
190+ * to hold the digest.
191+ */
192+ #if defined(HAVE_OPENSSL_CRYPTO )
193+ const EVP_MD * evp_md = crapi_alg_t_to_evp_md (alg );
194+ if (evp_md == NULL ) {
195+ errno = EINVAL ;
196+ return -1 ;
197+ }
198+ if (* size < (size_t )EVP_MD_size (evp_md )) {
199+ errno = ENOBUFS ;
200+ return -1 ;
201+ }
202+ #else
110203 int lib_alg = crapi_alg_t_to_lib_arg (alg );
111204#if defined(HAVE_NSS3 )
112205 if (* size < HASH_ResultLen (lib_alg )) {
@@ -116,6 +209,7 @@ int crapi_digest_fd(int fd, crapi_alg_t alg, void *dst, size_t *size)
116209 errno = ENOBUFS ;
117210 return -1 ;
118211 }
212+ #endif /* HAVE_OPENSSL_CRYPTO */
119213
120214 if (fstat (fd , & st ) != 0 )
121215 return (-1 );
@@ -129,6 +223,10 @@ int crapi_digest_fd(int fd, crapi_alg_t alg, void *dst, size_t *size)
129223# endif
130224 if (buffer == NULL ) {
131225#endif /* _FILE_OFFSET_BITS == 32 */
226+ #if defined(HAVE_OPENSSL_CRYPTO )
227+ if (crapi_digest_fd_stream (fd , evp_md , dst , size ) != 0 )
228+ return -1 ;
229+ #else
132230 uint8_t _buffer [CRAPI_IO_BUFSZ ];
133231 ssize_t ret ;
134232
@@ -181,10 +279,18 @@ int crapi_digest_fd(int fd, crapi_alg_t alg, void *dst, size_t *size)
181279 memcpy (dst , buffer , gcry_md_get_algo_dlen (lib_alg ));
182280 gcry_md_close (hd );
183281#endif
282+ #endif /* !HAVE_OPENSSL_CRYPTO */
184283
185284#if _FILE_OFFSET_BITS == 32
186285 } else {
187- #if defined(HAVE_NSS3 )
286+ #if defined(HAVE_OPENSSL_CRYPTO )
287+ unsigned int md_len = (unsigned int )* size ;
288+ if (EVP_Digest (buffer , buflen , (unsigned char * )dst , & md_len , evp_md , NULL ) != 1 ) {
289+ munmap (buffer , buflen );
290+ return -1 ;
291+ }
292+ * size = (size_t )md_len ;
293+ #elif defined(HAVE_NSS3 )
188294 HASH_HashBuf (lib_alg , (unsigned char * )dst , (unsigned char * )buffer , (unsigned int )buflen );
189295#elif defined(HAVE_GCRYPT )
190296 gcry_md_hash_buffer (lib_alg , dst , (const void * )buffer , buflen );
@@ -201,6 +307,8 @@ struct crapi_digest_ctx {
201307 HASHContext * ctx ;
202308#elif defined(HAVE_GCRYPT )
203309 gcry_md_hd_t ctx ;
310+ #elif defined(HAVE_OPENSSL_CRYPTO )
311+ EVP_MD_CTX * ctx ;
204312#endif
205313 void * dst ;
206314 size_t * size ;
@@ -215,14 +323,35 @@ static void *crapi_digest_init (void *dst, void *size, crapi_alg_t alg)
215323{
216324 struct crapi_digest_ctx * ctx = malloc (sizeof (struct crapi_digest_ctx ));
217325
326+ #if defined(HAVE_NSS3 ) || defined(HAVE_GCRYPT )
218327 int lib_alg = crapi_alg_t_to_lib_arg (alg );
328+ #endif
219329#if defined(HAVE_NSS3 )
220330 ctx -> ctx = HASH_Create (lib_alg );
221331#elif defined(HAVE_GCRYPT )
222332 if (gcry_md_open (& ctx -> ctx , lib_alg , 0 ) != 0 ) {
223333 free (ctx );
224334 return NULL ;
225335 }
336+ #elif defined(HAVE_OPENSSL_CRYPTO )
337+ if (ctx == NULL )
338+ return NULL ;
339+ const EVP_MD * evp_md = crapi_alg_t_to_evp_md (alg );
340+ if (evp_md == NULL ) {
341+ free (ctx );
342+ errno = EINVAL ;
343+ return NULL ;
344+ }
345+ ctx -> ctx = EVP_MD_CTX_new ();
346+ if (ctx -> ctx == NULL ) {
347+ free (ctx );
348+ return NULL ;
349+ }
350+ if (EVP_DigestInit_ex (ctx -> ctx , evp_md , NULL ) != 1 ) {
351+ EVP_MD_CTX_free (ctx -> ctx );
352+ free (ctx );
353+ return NULL ;
354+ }
226355#endif
227356 ctx -> dst = dst ;
228357 ctx -> size = size ;
@@ -245,6 +374,9 @@ static int crapi_digest_update(struct crapi_digest_ctx *ctx, void *bptr, size_t
245374 HASH_Update (ctx -> ctx , (const unsigned char * )bptr , (unsigned int )blen );
246375#elif defined(HAVE_GCRYPT )
247376 gcry_md_write (ctx -> ctx , (const void * )bptr , blen );
377+ #elif defined(HAVE_OPENSSL_CRYPTO )
378+ if (EVP_DigestUpdate (ctx -> ctx , (const void * )bptr , blen ) != 1 )
379+ return -1 ;
248380#endif
249381 return (0 );
250382}
@@ -264,6 +396,15 @@ static int crapi_digest_fini(struct crapi_digest_ctx *ctx, crapi_alg_t alg)
264396 buffer = (void * )gcry_md_read (ctx -> ctx , lib_alg );
265397 memcpy (ctx -> dst , buffer , gcry_md_get_algo_dlen (lib_alg ));
266398 gcry_md_close (ctx -> ctx );
399+ #elif defined(HAVE_OPENSSL_CRYPTO )
400+ unsigned int md_len = (unsigned int )* ctx -> size ;
401+ if (EVP_DigestFinal_ex (ctx -> ctx , (unsigned char * )ctx -> dst , & md_len ) != 1 ) {
402+ EVP_MD_CTX_free (ctx -> ctx );
403+ free (ctx );
404+ return -1 ;
405+ }
406+ * ctx -> size = (size_t )md_len ;
407+ EVP_MD_CTX_free (ctx -> ctx );
267408#endif
268409 free (ctx );
269410
@@ -275,6 +416,9 @@ static void crapi_digest_free(struct crapi_digest_ctx *ctx)
275416#if defined(HAVE_NSS3 )
276417 HASH_Destroy (ctx -> ctx );
277418 free (ctx );
419+ #elif defined(HAVE_OPENSSL_CRYPTO )
420+ EVP_MD_CTX_free (ctx -> ctx );
421+ free (ctx );
278422#endif
279423 return ;
280424}
0 commit comments