Alt-Digest-MD5-OpenSSL

 view release on metacpan or  search on metacpan

MD5.xs  view on Meta::CPAN

/*
 * This library is free software; you can redistribute it and/or
 * modify it under the same terms as Perl itself.
 *
 *  Copyright 2023-2026 Michal Josef Špaček.
 *  Copyright 1998-2000 Gisle Aas.
 *  Copyright 1995-1996 Neil Winton.
 *  Copyright 1991-1992 RSA Data Security, Inc.
 *
 * This code is derived from Neil Winton's MD5-1.7 Perl module, which in
 * turn is derived from the reference implementation in RFC 1321 which
 * comes with this message:
 *
 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
 * rights reserved.
 *
 * License to copy and use this software is granted provided that it
 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
 * Algorithm" in all material mentioning or referencing this software
 * or this function.
 *
 * License is also granted to make and use derivative works provided
 * that such works are identified as "derived from the RSA Data
 * Security, Inc. MD5 Message-Digest Algorithm" in all material
 * mentioning or referencing the derived work.
 *
 * RSA Data Security, Inc. makes no representations concerning either
 * the merchantability of this software or the suitability of this
 * software for any particular purpose. It is provided "as is"
 * without express or implied warranty of any kind.
 *
 * These notices must be retained in any copies of any part of this
 * documentation and/or software.
 */

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/evp.h>
#else
#include <openssl/md5.h>
#endif
#include <string.h>

/* Compatibility layer for OpenSSL 1.x and 3.x+ */
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
/* OpenSSL 3.x+ uses EVP API */
typedef struct {
    EVP_MD_CTX *ctx;
    unsigned int Nl;  /* For compatibility with addfile() offset logic */
} MD5_COMPAT_CTX;

#define MD5_DIGEST_LENGTH 16

static int md5_init(MD5_COMPAT_CTX *c) {
    c->ctx = EVP_MD_CTX_new();
    if (c->ctx == NULL)
        return 0;
    c->Nl = 0;
    return EVP_DigestInit_ex(c->ctx, EVP_md5(), NULL);
}

static int md5_update(MD5_COMPAT_CTX *c, const void *data, size_t len) {
    c->Nl += (unsigned int)len;
    return EVP_DigestUpdate(c->ctx, data, len);
}

static int md5_final(unsigned char *md, MD5_COMPAT_CTX *c) {
    unsigned int len;
    int ret = EVP_DigestFinal_ex(c->ctx, md, &len);
    EVP_MD_CTX_free(c->ctx);
    c->ctx = NULL;
    return ret;
}

static void md5_free(MD5_COMPAT_CTX *c) {
    if (c->ctx != NULL) {
        EVP_MD_CTX_free(c->ctx);
        c->ctx = NULL;
    }
}

#else
/* OpenSSL 1.x uses legacy MD5 API */
typedef MD5_CTX MD5_COMPAT_CTX;

static int md5_init(MD5_COMPAT_CTX *c) {
    return MD5_Init(c);
}

static int md5_update(MD5_COMPAT_CTX *c, const void *data, size_t len) {
    return MD5_Update(c, data, len);
}

static int md5_final(unsigned char *md, MD5_COMPAT_CTX *c) {
    return MD5_Final(md, c);
}

static void md5_free(MD5_COMPAT_CTX *c) {
    /* No cleanup needed for legacy API */
    (void)c;



( run in 0.938 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )