Path: blob/main/crypto/openssl/engines/e_padlock.c
34866 views
/*1* Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/*10* This file uses the low level AES and engine functions (which are deprecated11* for non-internal use) in order to implement the padlock engine AES ciphers.12*/13#define OPENSSL_SUPPRESS_DEPRECATED1415#include <stdio.h>16#include <string.h>1718#include <openssl/opensslconf.h>19#include <openssl/crypto.h>20#include <openssl/engine.h>21#include <openssl/evp.h>22#include <openssl/aes.h>23#include <openssl/rand.h>24#include <openssl/err.h>25#include <openssl/modes.h>2627#ifndef OPENSSL_NO_PADLOCKENG2829/*30* VIA PadLock AES is available *ONLY* on some x86 CPUs. Not only that it31* doesn't exist elsewhere, but it even can't be compiled on other platforms!32*/3334# undef COMPILE_PADLOCKENG35# if defined(PADLOCK_ASM)36# define COMPILE_PADLOCKENG37# ifdef OPENSSL_NO_DYNAMIC_ENGINE38static ENGINE *ENGINE_padlock(void);39# endif40# endif4142# ifdef OPENSSL_NO_DYNAMIC_ENGINE43void engine_load_padlock_int(void);44void engine_load_padlock_int(void)45{46/* On non-x86 CPUs it just returns. */47# ifdef COMPILE_PADLOCKENG48ENGINE *toadd = ENGINE_padlock();49if (!toadd)50return;51ERR_set_mark();52ENGINE_add(toadd);53/*54* If the "add" worked, it gets a structural reference. So either way, we55* release our just-created reference.56*/57ENGINE_free(toadd);58/*59* If the "add" didn't work, it was probably a conflict because it was60* already added (eg. someone calling ENGINE_load_blah then calling61* ENGINE_load_builtin_engines() perhaps).62*/63ERR_pop_to_mark();64# endif65}6667# endif6869# ifdef COMPILE_PADLOCKENG7071/* Function for ENGINE detection and control */72static int padlock_available(void);73static int padlock_init(ENGINE *e);7475/* RNG Stuff */76static RAND_METHOD padlock_rand;7778/* Cipher Stuff */79static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher,80const int **nids, int nid);8182/* Engine names */83static const char *padlock_id = "padlock";84static char padlock_name[100];8586/* Available features */87static int padlock_use_ace = 0; /* Advanced Cryptography Engine */88static int padlock_use_rng = 0; /* Random Number Generator */8990/* ===== Engine "management" functions ===== */9192/* Prepare the ENGINE structure for registration */93static int padlock_bind_helper(ENGINE *e)94{95/* Check available features */96padlock_available();9798/*99* RNG is currently disabled for reasons discussed in commentary just100* before padlock_rand_bytes function.101*/102padlock_use_rng = 0;103104/* Generate a nice engine name with available features */105BIO_snprintf(padlock_name, sizeof(padlock_name),106"VIA PadLock (%s, %s)",107padlock_use_rng ? "RNG" : "no-RNG",108padlock_use_ace ? "ACE" : "no-ACE");109110/* Register everything or return with an error */111if (!ENGINE_set_id(e, padlock_id) ||112!ENGINE_set_name(e, padlock_name) ||113!ENGINE_set_init_function(e, padlock_init) ||114(padlock_use_ace && !ENGINE_set_ciphers(e, padlock_ciphers)) ||115(padlock_use_rng && !ENGINE_set_RAND(e, &padlock_rand))) {116return 0;117}118119/* Everything looks good */120return 1;121}122123# ifdef OPENSSL_NO_DYNAMIC_ENGINE124/* Constructor */125static ENGINE *ENGINE_padlock(void)126{127ENGINE *eng = ENGINE_new();128129if (eng == NULL) {130return NULL;131}132133if (!padlock_bind_helper(eng)) {134ENGINE_free(eng);135return NULL;136}137138return eng;139}140# endif141142/* Check availability of the engine */143static int padlock_init(ENGINE *e)144{145return (padlock_use_rng || padlock_use_ace);146}147148# ifndef AES_ASM149static int padlock_aes_set_encrypt_key(const unsigned char *userKey,150const int bits,151AES_KEY *key);152static int padlock_aes_set_decrypt_key(const unsigned char *userKey,153const int bits,154AES_KEY *key);155# define AES_ASM156# define AES_set_encrypt_key padlock_aes_set_encrypt_key157# define AES_set_decrypt_key padlock_aes_set_decrypt_key158# include "../crypto/aes/aes_core.c"159# endif160161/*162* This stuff is needed if this ENGINE is being compiled into a163* self-contained shared-library.164*/165# ifndef OPENSSL_NO_DYNAMIC_ENGINE166static int padlock_bind_fn(ENGINE *e, const char *id)167{168if (id && (strcmp(id, padlock_id) != 0)) {169return 0;170}171172if (!padlock_bind_helper(e)) {173return 0;174}175176return 1;177}178179IMPLEMENT_DYNAMIC_CHECK_FN()180IMPLEMENT_DYNAMIC_BIND_FN(padlock_bind_fn)181# endif /* !OPENSSL_NO_DYNAMIC_ENGINE */182/* ===== Here comes the "real" engine ===== */183184/* Some AES-related constants */185# define AES_BLOCK_SIZE 16186# define AES_KEY_SIZE_128 16187# define AES_KEY_SIZE_192 24188# define AES_KEY_SIZE_256 32189/*190* Here we store the status information relevant to the current context.191*/192/*193* BIG FAT WARNING: Inline assembler in PADLOCK_XCRYPT_ASM() depends on194* the order of items in this structure. Don't blindly modify, reorder,195* etc!196*/197struct padlock_cipher_data {198unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */199union {200unsigned int pad[4];201struct {202int rounds:4;203int dgst:1; /* n/a in C3 */204int align:1; /* n/a in C3 */205int ciphr:1; /* n/a in C3 */206unsigned int keygen:1;207int interm:1;208unsigned int encdec:1;209int ksize:2;210} b;211} cword; /* Control word */212AES_KEY ks; /* Encryption key */213};214215/* Interface to assembler module */216unsigned int padlock_capability(void);217void padlock_key_bswap(AES_KEY *key);218void padlock_verify_context(struct padlock_cipher_data *ctx);219void padlock_reload_key(void);220void padlock_aes_block(void *out, const void *inp,221struct padlock_cipher_data *ctx);222int padlock_ecb_encrypt(void *out, const void *inp,223struct padlock_cipher_data *ctx, size_t len);224int padlock_cbc_encrypt(void *out, const void *inp,225struct padlock_cipher_data *ctx, size_t len);226int padlock_cfb_encrypt(void *out, const void *inp,227struct padlock_cipher_data *ctx, size_t len);228int padlock_ofb_encrypt(void *out, const void *inp,229struct padlock_cipher_data *ctx, size_t len);230int padlock_ctr32_encrypt(void *out, const void *inp,231struct padlock_cipher_data *ctx, size_t len);232int padlock_xstore(void *out, int edx);233void padlock_sha1_oneshot(void *ctx, const void *inp, size_t len);234void padlock_sha1(void *ctx, const void *inp, size_t len);235void padlock_sha256_oneshot(void *ctx, const void *inp, size_t len);236void padlock_sha256(void *ctx, const void *inp, size_t len);237238/*239* Load supported features of the CPU to see if the PadLock is available.240*/241static int padlock_available(void)242{243unsigned int edx = padlock_capability();244245/* Fill up some flags */246padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6));247padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2));248249return padlock_use_ace + padlock_use_rng;250}251252/* ===== AES encryption/decryption ===== */253254# if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)255# define NID_aes_128_cfb NID_aes_128_cfb128256# endif257258# if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)259# define NID_aes_128_ofb NID_aes_128_ofb128260# endif261262# if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)263# define NID_aes_192_cfb NID_aes_192_cfb128264# endif265266# if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)267# define NID_aes_192_ofb NID_aes_192_ofb128268# endif269270# if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)271# define NID_aes_256_cfb NID_aes_256_cfb128272# endif273274# if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)275# define NID_aes_256_ofb NID_aes_256_ofb128276# endif277278/* List of supported ciphers. */279static const int padlock_cipher_nids[] = {280NID_aes_128_ecb,281NID_aes_128_cbc,282NID_aes_128_cfb,283NID_aes_128_ofb,284NID_aes_128_ctr,285286NID_aes_192_ecb,287NID_aes_192_cbc,288NID_aes_192_cfb,289NID_aes_192_ofb,290NID_aes_192_ctr,291292NID_aes_256_ecb,293NID_aes_256_cbc,294NID_aes_256_cfb,295NID_aes_256_ofb,296NID_aes_256_ctr297};298299static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids) /300sizeof(padlock_cipher_nids[0]));301302/* Function prototypes ... */303static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,304const unsigned char *iv, int enc);305306# define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \307( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )308# define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\309NEAREST_ALIGNED(EVP_CIPHER_CTX_get_cipher_data(ctx)))310311static int312padlock_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,313const unsigned char *in_arg, size_t nbytes)314{315return padlock_ecb_encrypt(out_arg, in_arg,316ALIGNED_CIPHER_DATA(ctx), nbytes);317}318319static int320padlock_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,321const unsigned char *in_arg, size_t nbytes)322{323struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);324int ret;325326memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE);327if ((ret = padlock_cbc_encrypt(out_arg, in_arg, cdata, nbytes)))328memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE);329return ret;330}331332static int333padlock_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,334const unsigned char *in_arg, size_t nbytes)335{336struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);337size_t chunk;338339if ((chunk = EVP_CIPHER_CTX_get_num(ctx))) { /* borrow chunk variable */340unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx);341342if (chunk >= AES_BLOCK_SIZE)343return 0; /* bogus value */344345if (EVP_CIPHER_CTX_is_encrypting(ctx))346while (chunk < AES_BLOCK_SIZE && nbytes != 0) {347ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];348chunk++, nbytes--;349} else350while (chunk < AES_BLOCK_SIZE && nbytes != 0) {351unsigned char c = *(in_arg++);352*(out_arg++) = c ^ ivp[chunk];353ivp[chunk++] = c, nbytes--;354}355356EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE);357}358359if (nbytes == 0)360return 1;361362memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE);363364if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) {365if (!padlock_cfb_encrypt(out_arg, in_arg, cdata, chunk))366return 0;367nbytes -= chunk;368}369370if (nbytes) {371unsigned char *ivp = cdata->iv;372373out_arg += chunk;374in_arg += chunk;375EVP_CIPHER_CTX_set_num(ctx, nbytes);376if (cdata->cword.b.encdec) {377cdata->cword.b.encdec = 0;378padlock_reload_key();379padlock_aes_block(ivp, ivp, cdata);380cdata->cword.b.encdec = 1;381padlock_reload_key();382while (nbytes) {383unsigned char c = *(in_arg++);384*(out_arg++) = c ^ *ivp;385*(ivp++) = c, nbytes--;386}387} else {388padlock_reload_key();389padlock_aes_block(ivp, ivp, cdata);390padlock_reload_key();391while (nbytes) {392*ivp = *(out_arg++) = *(in_arg++) ^ *ivp;393ivp++, nbytes--;394}395}396}397398memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE);399400return 1;401}402403static int404padlock_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,405const unsigned char *in_arg, size_t nbytes)406{407struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);408size_t chunk;409410/*411* ctx->num is maintained in byte-oriented modes, such as CFB and OFB...412*/413if ((chunk = EVP_CIPHER_CTX_get_num(ctx))) { /* borrow chunk variable */414unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx);415416if (chunk >= AES_BLOCK_SIZE)417return 0; /* bogus value */418419while (chunk < AES_BLOCK_SIZE && nbytes != 0) {420*(out_arg++) = *(in_arg++) ^ ivp[chunk];421chunk++, nbytes--;422}423424EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE);425}426427if (nbytes == 0)428return 1;429430memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE);431432if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) {433if (!padlock_ofb_encrypt(out_arg, in_arg, cdata, chunk))434return 0;435nbytes -= chunk;436}437438if (nbytes) {439unsigned char *ivp = cdata->iv;440441out_arg += chunk;442in_arg += chunk;443EVP_CIPHER_CTX_set_num(ctx, nbytes);444padlock_reload_key(); /* empirically found */445padlock_aes_block(ivp, ivp, cdata);446padlock_reload_key(); /* empirically found */447while (nbytes) {448*(out_arg++) = *(in_arg++) ^ *ivp;449ivp++, nbytes--;450}451}452453memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE);454455return 1;456}457458static void padlock_ctr32_encrypt_glue(const unsigned char *in,459unsigned char *out, size_t blocks,460struct padlock_cipher_data *ctx,461const unsigned char *ivec)462{463memcpy(ctx->iv, ivec, AES_BLOCK_SIZE);464padlock_ctr32_encrypt(out, in, ctx, AES_BLOCK_SIZE * blocks);465}466467static int468padlock_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,469const unsigned char *in_arg, size_t nbytes)470{471struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);472int n = EVP_CIPHER_CTX_get_num(ctx);473unsigned int num;474475if (n < 0)476return 0;477num = (unsigned int)n;478479CRYPTO_ctr128_encrypt_ctr32(in_arg, out_arg, nbytes,480cdata, EVP_CIPHER_CTX_iv_noconst(ctx),481EVP_CIPHER_CTX_buf_noconst(ctx), &num,482(ctr128_f) padlock_ctr32_encrypt_glue);483484EVP_CIPHER_CTX_set_num(ctx, (size_t)num);485return 1;486}487488# define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE489# define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE490# define EVP_CIPHER_block_size_OFB 1491# define EVP_CIPHER_block_size_CFB 1492# define EVP_CIPHER_block_size_CTR 1493494/*495* Declaring so many ciphers by hand would be a pain. Instead introduce a bit496* of preprocessor magic :-)497*/498# define DECLARE_AES_EVP(ksize,lmode,umode) \499static EVP_CIPHER *_hidden_aes_##ksize##_##lmode = NULL; \500static const EVP_CIPHER *padlock_aes_##ksize##_##lmode(void) \501{ \502if (_hidden_aes_##ksize##_##lmode == NULL \503&& ((_hidden_aes_##ksize##_##lmode = \504EVP_CIPHER_meth_new(NID_aes_##ksize##_##lmode, \505EVP_CIPHER_block_size_##umode, \506AES_KEY_SIZE_##ksize)) == NULL \507|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_##ksize##_##lmode, \508AES_BLOCK_SIZE) \509|| !EVP_CIPHER_meth_set_flags(_hidden_aes_##ksize##_##lmode, \5100 | EVP_CIPH_##umode##_MODE) \511|| !EVP_CIPHER_meth_set_init(_hidden_aes_##ksize##_##lmode, \512padlock_aes_init_key) \513|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_##ksize##_##lmode, \514padlock_##lmode##_cipher) \515|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_##ksize##_##lmode, \516sizeof(struct padlock_cipher_data) + 16) \517|| !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_##ksize##_##lmode, \518EVP_CIPHER_set_asn1_iv) \519|| !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_##ksize##_##lmode, \520EVP_CIPHER_get_asn1_iv))) { \521EVP_CIPHER_meth_free(_hidden_aes_##ksize##_##lmode); \522_hidden_aes_##ksize##_##lmode = NULL; \523} \524return _hidden_aes_##ksize##_##lmode; \525}526527DECLARE_AES_EVP(128, ecb, ECB)528DECLARE_AES_EVP(128, cbc, CBC)529DECLARE_AES_EVP(128, cfb, CFB)530DECLARE_AES_EVP(128, ofb, OFB)531DECLARE_AES_EVP(128, ctr, CTR)532533DECLARE_AES_EVP(192, ecb, ECB)534DECLARE_AES_EVP(192, cbc, CBC)535DECLARE_AES_EVP(192, cfb, CFB)536DECLARE_AES_EVP(192, ofb, OFB)537DECLARE_AES_EVP(192, ctr, CTR)538539DECLARE_AES_EVP(256, ecb, ECB)540DECLARE_AES_EVP(256, cbc, CBC)541DECLARE_AES_EVP(256, cfb, CFB)542DECLARE_AES_EVP(256, ofb, OFB)543DECLARE_AES_EVP(256, ctr, CTR)544545static int546padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids,547int nid)548{549/* No specific cipher => return a list of supported nids ... */550if (!cipher) {551*nids = padlock_cipher_nids;552return padlock_cipher_nids_num;553}554555/* ... or the requested "cipher" otherwise */556switch (nid) {557case NID_aes_128_ecb:558*cipher = padlock_aes_128_ecb();559break;560case NID_aes_128_cbc:561*cipher = padlock_aes_128_cbc();562break;563case NID_aes_128_cfb:564*cipher = padlock_aes_128_cfb();565break;566case NID_aes_128_ofb:567*cipher = padlock_aes_128_ofb();568break;569case NID_aes_128_ctr:570*cipher = padlock_aes_128_ctr();571break;572573case NID_aes_192_ecb:574*cipher = padlock_aes_192_ecb();575break;576case NID_aes_192_cbc:577*cipher = padlock_aes_192_cbc();578break;579case NID_aes_192_cfb:580*cipher = padlock_aes_192_cfb();581break;582case NID_aes_192_ofb:583*cipher = padlock_aes_192_ofb();584break;585case NID_aes_192_ctr:586*cipher = padlock_aes_192_ctr();587break;588589case NID_aes_256_ecb:590*cipher = padlock_aes_256_ecb();591break;592case NID_aes_256_cbc:593*cipher = padlock_aes_256_cbc();594break;595case NID_aes_256_cfb:596*cipher = padlock_aes_256_cfb();597break;598case NID_aes_256_ofb:599*cipher = padlock_aes_256_ofb();600break;601case NID_aes_256_ctr:602*cipher = padlock_aes_256_ctr();603break;604605default:606/* Sorry, we don't support this NID */607*cipher = NULL;608return 0;609}610611return 1;612}613614/* Prepare the encryption key for PadLock usage */615static int616padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,617const unsigned char *iv, int enc)618{619struct padlock_cipher_data *cdata;620int key_len = EVP_CIPHER_CTX_get_key_length(ctx) * 8;621unsigned long mode = EVP_CIPHER_CTX_get_mode(ctx);622623if (key == NULL)624return 0; /* ERROR */625626cdata = ALIGNED_CIPHER_DATA(ctx);627memset(cdata, 0, sizeof(*cdata));628629/* Prepare Control word. */630if (mode == EVP_CIPH_OFB_MODE || mode == EVP_CIPH_CTR_MODE)631cdata->cword.b.encdec = 0;632else633cdata->cword.b.encdec = (EVP_CIPHER_CTX_is_encrypting(ctx) == 0);634cdata->cword.b.rounds = 10 + (key_len - 128) / 32;635cdata->cword.b.ksize = (key_len - 128) / 64;636637switch (key_len) {638case 128:639/*640* PadLock can generate an extended key for AES128 in hardware641*/642memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);643cdata->cword.b.keygen = 0;644break;645646case 192:647case 256:648/*649* Generate an extended AES key in software. Needed for AES192/AES256650*/651/*652* Well, the above applies to Stepping 8 CPUs and is listed as653* hardware errata. They most likely will fix it at some point and654* then a check for stepping would be due here.655*/656if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)657&& !enc)658AES_set_decrypt_key(key, key_len, &cdata->ks);659else660AES_set_encrypt_key(key, key_len, &cdata->ks);661/*662* OpenSSL C functions use byte-swapped extended key.663*/664padlock_key_bswap(&cdata->ks);665cdata->cword.b.keygen = 1;666break;667668default:669/* ERROR */670return 0;671}672673/*674* This is done to cover for cases when user reuses the675* context for new key. The catch is that if we don't do676* this, padlock_eas_cipher might proceed with old key...677*/678padlock_reload_key();679680return 1;681}682683/* ===== Random Number Generator ===== */684/*685* This code is not engaged. The reason is that it does not comply686* with recommendations for VIA RNG usage for secure applications687* (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it688* provide meaningful error control...689*/690/*691* Wrapper that provides an interface between the API and the raw PadLock692* RNG693*/694static int padlock_rand_bytes(unsigned char *output, int count)695{696unsigned int eax, buf;697698while (count >= 8) {699eax = padlock_xstore(output, 0);700if (!(eax & (1 << 6)))701return 0; /* RNG disabled */702/* this ---vv--- covers DC bias, Raw Bits and String Filter */703if (eax & (0x1F << 10))704return 0;705if ((eax & 0x1F) == 0)706continue; /* no data, retry... */707if ((eax & 0x1F) != 8)708return 0; /* fatal failure... */709output += 8;710count -= 8;711}712while (count > 0) {713eax = padlock_xstore(&buf, 3);714if (!(eax & (1 << 6)))715return 0; /* RNG disabled */716/* this ---vv--- covers DC bias, Raw Bits and String Filter */717if (eax & (0x1F << 10))718return 0;719if ((eax & 0x1F) == 0)720continue; /* no data, retry... */721if ((eax & 0x1F) != 1)722return 0; /* fatal failure... */723*output++ = (unsigned char)buf;724count--;725}726OPENSSL_cleanse(&buf, sizeof(buf));727728return 1;729}730731/* Dummy but necessary function */732static int padlock_rand_status(void)733{734return 1;735}736737/* Prepare structure for registration */738static RAND_METHOD padlock_rand = {739NULL, /* seed */740padlock_rand_bytes, /* bytes */741NULL, /* cleanup */742NULL, /* add */743padlock_rand_bytes, /* pseudorand */744padlock_rand_status, /* rand status */745};746747# endif /* COMPILE_PADLOCKENG */748#endif /* !OPENSSL_NO_PADLOCKENG */749750#if defined(OPENSSL_NO_PADLOCKENG) || !defined(COMPILE_PADLOCKENG)751# ifndef OPENSSL_NO_DYNAMIC_ENGINE752OPENSSL_EXPORT753int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);754OPENSSL_EXPORT755int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns)756{757return 0;758}759760IMPLEMENT_DYNAMIC_CHECK_FN()761# endif762#endif763764765