Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.3
compat-openssl097g
openssl-0.9.7d-padlock-engine.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssl-0.9.7d-padlock-engine.diff of Package compat-openssl097g
Index: crypto/engine/hw_padlock.c =================================================================== --- /dev/null +++ crypto/engine/hw_padlock.c @@ -0,0 +1,734 @@ +/* + * Support for VIA PadLock Advanced Cryptography Engine (ACE) + * Written by Michal Ludvig <michal@logix.cz> + * http://www.logix.cz/michal + * + * Date: May 13, 2004 + */ + +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include <netinet/in.h> /* we need htonl() */ + +#include <openssl/crypto.h> +#include <openssl/dso.h> +#include <openssl/engine.h> +#include <openssl/evp.h> +#include <openssl/aes.h> + +#ifndef OPENSSL_NO_HW +#ifndef OPENSSL_NO_HW_PADLOCK + +/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */ +#if (OPENSSL_VERSION_NUMBER >= 0x00908000L) +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define DYNAMIC_ENGINE +# endif +#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# ifdef ENGINE_DYNAMIC_SUPPORT +# define DYNAMIC_ENGINE +# endif +#else +# error "Only OpenSSL >= 0.9.7 is supported" +#endif + +/* VIA PadLock AES is available *ONLY* on some x86 CPUs. + Not only that it doesn't exist elsewhere, but it + even can't be compiled on other platforms! + + In addition, because of the heavy use of inline assembler, + you must use GNU GCC for now. This is not a "technology + limitation", I simply didn't have a chance to test other + compilers and instead chosen the safe way :-) */ +#if defined(__i386__) && !defined(__amd64__) && defined(__GNUC__) +#define COMPILE_HW_PADLOCK +#else +#undef COMPILE_HW_PADLOCK +#endif + +static ENGINE *ENGINE_padlock (void); + +void ENGINE_load_padlock (void) +{ +/* On non-x86 CPUs it just returns. */ +#ifdef COMPILE_HW_PADLOCK + ENGINE *toadd = ENGINE_padlock (); + if (!toadd) return; + ENGINE_add (toadd); + ENGINE_free (toadd); + ERR_clear_error (); +#endif +} + +#ifdef COMPILE_HW_PADLOCK +/* Function for ENGINE detection and control */ +static int padlock_available(void); +static int padlock_init(ENGINE *e); + +/* RNG Stuff */ +static RAND_METHOD padlock_rand; + +/* Cipher Stuff */ +static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + +/* Engine names */ +static const char *padlock_id = "padlock"; +static char padlock_name[100]; + +/* Available features */ +static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ +static int padlock_use_rng = 0; /* Random Number Generator */ + +/* ===== Engine "management" functions ===== */ + +/* Prepare the ENGINE structure for registration */ +static int +padlock_bind_helper(ENGINE *e) +{ + /* Check available features */ + padlock_available(); + + /* Generate a nice engine name with available features */ + snprintf(padlock_name, sizeof(padlock_name), "VIA PadLock (%s, %s)", + padlock_use_rng ? "RNG" : "no-RNG", + padlock_use_ace ? "ACE" : "no-ACE"); + + /* Register everything or return with an error */ + if (!ENGINE_set_id(e, padlock_id) || + !ENGINE_set_name(e, padlock_name) || + + !ENGINE_set_init_function(e, padlock_init) || + + (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) || + (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) { + return 0; + } + + /* Everything looks good */ + return 1; +} + +/* Constructor */ +static ENGINE * +ENGINE_padlock(void) +{ + ENGINE *eng = ENGINE_new(); + + if (!eng) { + return NULL; + } + + if (!padlock_bind_helper(eng)) { + ENGINE_free(eng); + return NULL; + } + + return eng; +} + +/* Helper function - check if a CPUID instruction + is available on this CPU */ +static int +padlock_insn_cpuid_available(void) +{ + uint32_t result = -1; + + /* TODO: handle the "red-zone" once this + module is enabled on AMD64 */ + /* We're checking if the bit #21 of EFLAGS + can be toggled. If yes = CPUID is available. */ + asm volatile ( + "pushf\n" + "popl %%eax\n" + "xorl $0x200000, %%eax\n" + "movl %%eax, %%ecx\n" + "andl $0x200000, %%ecx\n" + "pushl %%eax\n" + "popf\n" + "pushf\n" + "popl %%eax\n" + "andl $0x200000, %%eax\n" + "xorl %%eax, %%ecx\n" + "movl %%ecx, %0\n" + : "=r" (result) : : "eax", "ecx"); + + return (result == 0); +} + +static int +padlock_available(void) +{ + uint32_t eax, edx; + + /* First check if the CPUID instruction is available at all... */ + if (! padlock_insn_cpuid_available()) + return 0; + + /* Check for Centaur Extended Feature Flags presence */ + eax = 0xC0000000; + asm volatile ("pushl %%ebx; cpuid; popl %%ebx" : "+a"(eax) : : "ecx", "edx"); + if (eax < 0xC0000001) + return 0; + + /* Read the Centaur Extended Feature Flags */ + eax = 0xC0000001; + asm volatile ("pushl %%ebx; cpuid; popl %%ebx" : "+a"(eax), "=d"(edx) : : "ecx"); + + /* Fill up some flags */ + padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6)); + padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2)); + + return padlock_use_ace + padlock_use_rng; +} + +/* Check availability of the engine */ +static int +padlock_init(ENGINE *e) +{ + return (padlock_use_rng || padlock_use_ace); +} + +/* This stuff is needed if this ENGINE is being compiled into a self-contained + * shared-library. + */ +#ifdef DYNAMIC_ENGINE +static int +padlock_bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, padlock_id) != 0)) { + return 0; + } + + if (!padlock_bind_helper(e)) { + return 0; + } + + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN (); +IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn); +#endif /* DYNAMIC_ENGINE */ + +/* ===== Here comes the "real" engine ===== */ + +#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb) +#define NID_aes_128_cfb NID_aes_128_cfb128 +#endif + +#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb) +#define NID_aes_128_ofb NID_aes_128_ofb128 +#endif + +#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb) +#define NID_aes_192_cfb NID_aes_192_cfb128 +#endif + +#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb) +#define NID_aes_192_ofb NID_aes_192_ofb128 +#endif + +#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb) +#define NID_aes_256_cfb NID_aes_256_cfb128 +#endif + +#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb) +#define NID_aes_256_ofb NID_aes_256_ofb128 +#endif + +/* List of supported ciphers. */ +static int padlock_cipher_nids[] = { + NID_aes_128_ecb, + NID_aes_128_cbc, + NID_aes_128_cfb, + NID_aes_128_ofb, + + NID_aes_192_ecb, + NID_aes_192_cbc, +// NID_aes_192_cfb, /* FIXME: AES192/256 CFB/OFB don't work. */ +// NID_aes_192_ofb, + + NID_aes_256_ecb, + NID_aes_256_cbc, +// NID_aes_256_cfb, +// NID_aes_256_ofb, +}; +static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/ + sizeof(padlock_cipher_nids[0])); + +/* Function prototypes ... */ +static int padlock_aes_init_key_128(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int padlock_aes_init_key_192(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int padlock_aes_init_key_256(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl); + +/* Some AES-related constants */ +#define AES_BLOCK_SIZE 16 +#define AES_KEY_SIZE_128 16 +#define AES_KEY_SIZE_192 24 +#define AES_KEY_SIZE_256 32 + +#define AES_KEY_WORDS (4 * (AES_MAXNR + 1)) +#define AES_KEY_BYTES (AES_KEY_WORDS * 4) + +/* Here we store the plain key for AES128 + and the extended key for AES192/AES256 */ +struct padlock_aes_key +{ + uint32_t aes_key[AES_KEY_WORDS]; + int extended; +}; + +/* Declaring so many ciphers by hand would be a pain. + Instead introduce a bit of preprocessor magic :-) */ +#define DECLARE_AES_EVP(ksize,lmode,umode) \ +static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \ + NID_aes_##ksize##_##lmode, \ + AES_BLOCK_SIZE, \ + AES_KEY_SIZE_##ksize, \ + AES_BLOCK_SIZE, \ + 0 | EVP_CIPH_##umode##_MODE, \ + padlock_aes_init_key_##ksize, \ + padlock_aes_cipher, \ + NULL, \ + sizeof(struct padlock_aes_key), \ + EVP_CIPHER_set_asn1_iv, \ + EVP_CIPHER_get_asn1_iv, \ + NULL, \ + NULL \ +} + +DECLARE_AES_EVP(128,ecb,ECB); +DECLARE_AES_EVP(128,cbc,CBC); +DECLARE_AES_EVP(128,cfb,CFB); +DECLARE_AES_EVP(128,ofb,OFB); + +DECLARE_AES_EVP(192,ecb,ECB); +DECLARE_AES_EVP(192,cbc,CBC); +DECLARE_AES_EVP(192,cfb,CFB); +DECLARE_AES_EVP(192,ofb,OFB); + +DECLARE_AES_EVP(256,ecb,ECB); +DECLARE_AES_EVP(256,cbc,CBC); +DECLARE_AES_EVP(256,cfb,CFB); +DECLARE_AES_EVP(256,ofb,OFB); + +static int +padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid) +{ + /* No specific cipher => return a list of supported nids ... */ + if (!cipher) { + *nids = padlock_cipher_nids; + return padlock_cipher_nids_num; + } + + /* ... or the requested "cipher" otherwise */ + switch (nid) { + case NID_aes_128_ecb: + *cipher = &padlock_aes_128_ecb; + break; + case NID_aes_128_cbc: + *cipher = &padlock_aes_128_cbc; + break; + case NID_aes_128_cfb: + *cipher = &padlock_aes_128_cfb; + break; + case NID_aes_128_ofb: + *cipher = &padlock_aes_128_ofb; + break; + + case NID_aes_192_ecb: + *cipher = &padlock_aes_192_ecb; + break; + case NID_aes_192_cbc: + *cipher = &padlock_aes_192_cbc; + break; + case NID_aes_192_cfb: + *cipher = &padlock_aes_192_cfb; + break; + case NID_aes_192_ofb: + *cipher = &padlock_aes_192_ofb; + break; + + case NID_aes_256_ecb: + *cipher = &padlock_aes_256_ecb; + break; + case NID_aes_256_cbc: + *cipher = &padlock_aes_256_cbc; + break; + case NID_aes_256_cfb: + *cipher = &padlock_aes_256_cfb; + break; + case NID_aes_256_ofb: + *cipher = &padlock_aes_256_ofb; + break; + + default: + /* Sorry, we don't support this NID */ + *cipher = NULL; + return 0; + } + + return 1; +} + +/* Generate an extended AES key in software. Needed for AES192/AES256 */ +static int +padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc, + int key_len) +{ + AES_KEY ks; + struct padlock_aes_key *tmp_aes_key = NULL; + int i; + + tmp_aes_key = (struct padlock_aes_key *) (ctx->cipher_data); + memset(tmp_aes_key, 0, sizeof(struct padlock_aes_key)); + if (key) { + if (enc) + AES_set_encrypt_key(key, key_len, &ks); + else + AES_set_decrypt_key(key, key_len, &ks); + + /* OpenSSL internal functions use byte-swapped extended key. */ + for (i = 0; i < AES_KEY_WORDS; i++) + tmp_aes_key->aes_key[i] = htonl(ks.rd_key[i]); + + tmp_aes_key->extended = 1; + } + + return 1; +} + +/* PadLock can generate an extended key for AES128 in hardware */ +static int +padlock_aes_init_key_128(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + struct padlock_aes_key *tmp_aes_key = NULL; + + tmp_aes_key = (struct padlock_aes_key *) (ctx->cipher_data); + memset(tmp_aes_key, 0, sizeof(struct padlock_aes_key)); + if (key) { + memcpy (tmp_aes_key->aes_key, key, AES_KEY_SIZE_128); + tmp_aes_key->extended = 0; + } + + return 1; +} + +static int +padlock_aes_init_key_192(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + return padlock_aes_init_key(ctx, key, iv, enc, 192); +} + +static int +padlock_aes_init_key_256(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + return padlock_aes_init_key(ctx, key, iv, enc, 256); +} + +/* Data for the VIA PadLock *must* be aligned on 16-Bytes boundaries! */ +static void * +padlock_aligned_malloc(size_t size, size_t alignment, void **index) +{ + char *ptr; + + ptr = malloc(size + alignment); + *index = ptr; + if (alignment > 1 && ((long)ptr & (alignment - 1))) { + ptr += alignment - ((long)ptr & (alignment - 1)); + } + + return ptr; +} + +/* Control word. */ +union cword { + uint32_t cword[4]; + struct { + int rounds:4; + int algo:3; + int keygen:1; + int interm:1; + int encdec:1; + int ksize:2; + } b; +}; + +/* Template for all modes */ +#define PADLOCK_XCRYPT_ASM(name,opcode) \ +static inline void name(uint8_t *input, uint8_t *output, uint8_t *key, \ + uint8_t **iv, void *control_word, uint32_t count) \ +{ \ + asm volatile ("pushfl; popfl\n" \ + "movl %%ebx, -4(%%esp)\n" \ + "movl %%eax, %%ebx\n" \ + "movl %0, %%eax\n" \ + "movl (%%eax), %%eax\n" \ + opcode "\n" \ + "movl %0, %%ebx\n" \ + "movl %%eax, (%%ebx)\n" \ + "movl -4(%%esp), %%ebx\n" \ + : "+m"(iv), "+S"(input), "+D"(output) \ + : "a"(key), "c"(count), "d"(control_word)); \ +} + +/* Generate all functions with appropriate opcodes */ +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8"); /* rep xcryptecb */ +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0"); /* rep xcryptcbc */ +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0"); /* rep xcryptcfb */ +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8"); /* rep xcryptofb */ + +/* Re-align the arguments to 16-Bytes boundaries and run the + encryption function itself. This function is not AES-specific. */ +static inline void +padlock_aligner(uint8_t *out_arg, const uint8_t *in_arg, uint8_t *iv_arg, + void *key, union cword *cword, size_t nbytes, + size_t blocksize, int mode) +{ + /* Don't blindly modify this structure - the items must + be 16-Bytes aligned! */ + struct padlock_xcrypt_data { + uint8_t iv[2*blocksize]; /* Initialization vector */ + }; + + uint8_t *in, *out, *iv; + void *index = NULL; + char bigbuf[sizeof(struct padlock_xcrypt_data) + 16]; + struct padlock_xcrypt_data *data; + + memset(bigbuf, 0, sizeof (bigbuf)); + + /* Place 'data' at the first 16-Bytes aligned address in 'bigbuf' */ + if (((long)bigbuf) & 0x0F) + data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F)); + else + data = (void*)bigbuf; + + /* Always make a local copy of IV - xcrypt may change it! */ + iv = data->iv; + if (iv_arg) + memcpy(iv, iv_arg, blocksize); + + /* Align 'in_arg' */ + if (((long)in_arg) & 0x0F) { + in = padlock_aligned_malloc(nbytes, 16, &index); + memcpy(in, in_arg, nbytes); + } + else + in = (uint8_t*)in_arg; + + /* Align 'out_arg' */ + if (((long)out_arg) & 0x0F) { + if (index) + out = in; /* xcrypt can work "in place" */ + else + out = padlock_aligned_malloc(nbytes, 16, &index); + } + else + out = out_arg; + + /* Run xcrypt for a requested mode */ + switch (mode) { + case EVP_CIPH_ECB_MODE: + padlock_xcrypt_ecb(in, out, key, &iv, cword, nbytes/blocksize); + break; + + case EVP_CIPH_CBC_MODE: + padlock_xcrypt_cbc(in, out, key, &iv, cword, nbytes/blocksize); + break; + + case EVP_CIPH_CFB_MODE: + padlock_xcrypt_cfb(in, out, key, &iv, cword, nbytes/blocksize); + break; + + case EVP_CIPH_OFB_MODE: + padlock_xcrypt_ofb(in, out, key, &iv, cword, nbytes/blocksize); + break; + + default: + break; + } + + /* Copy the 16-Byte aligned output to the caller's buffer. */ + if (out != out_arg) + memcpy(out_arg, out, nbytes); + + /* Save modified IV */ + memcpy (iv_arg, iv, blocksize); + + if (index) + free(index); + +} + +/* Entry point specific for AES cipher */ +static int +padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int in_len) +{ + char bigbuf[sizeof(union cword) + 16]; + union cword *cword; + void *key_arg, *key, *iv, *index_key=NULL; + int mode = EVP_CIPHER_CTX_mode(ctx); + int key_len = EVP_CIPHER_CTX_key_length(ctx); + struct padlock_aes_key *aes_key = (struct padlock_aes_key *) (ctx->cipher_data); + + /* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */ + if (((long)bigbuf) & 0x0F) + cword = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F)); + else + cword = (void*)bigbuf; + + /* Prepare Control word. */ + memset (cword, 0, sizeof(union cword)); + cword->b.encdec = (ctx->encrypt == 0); + cword->b.rounds = 10 + (key_len - 16) / 4; + cword->b.ksize = (key_len - 16) / 8; + cword->b.keygen = aes_key->extended; + + key_arg = aes_key->aes_key; + if ((long)key_arg & 0x0f) { + key = padlock_aligned_malloc(AES_KEY_BYTES, 16, &index_key); + memcpy (key, key_arg, AES_KEY_BYTES); + } else + key = key_arg; + + iv = ctx->iv; + + padlock_aligner(out, in, iv, key, cword, + in_len, AES_BLOCK_SIZE, mode); + + if (index_key) + free(index_key); + + return 1; +} + +/* ===== Random Number Generator ===== */ + +/* The RNG call itself */ +static inline uint32_t +padlock_xstore(unsigned char **output_addr, uint32_t edx_in, + uint32_t count) +{ + uint32_t eax_out; + + asm volatile (".byte 0xf3,0x0f,0xa7,0xc0" /* rep xstore */ + : "+D"(*output_addr), "=a"(eax_out) /* output */ + : "d" (edx_in), "c"(count) /* input */ + ); + + return eax_out; +} + +/* Wrapper that provides an interface between the API and + the raw PadLock RNG */ +static int +padlock_rand_bytes(unsigned char *output, int count) +{ + unsigned char *pptr = output; + unsigned char buf[8]; + int orig_count = count; + + /* xstore always stores at least 4 bytes - we must avoid + overwriting of innocent data! */ + if (count > 4) { + /* 3 ... magic constant, see PadLock RNG docs */ + padlock_xstore(&pptr, 3, count - 4); + count = 4; + } + if (count > 0) { + pptr = buf; + padlock_xstore(&pptr, 3, count); + memcpy(output + orig_count - count, buf, count); + } + return 1; +} + +/* Dummy but necessary function */ +static int +padlock_rand_status(void) +{ + return 1; +} + +/* Prepare structure for registration */ +static RAND_METHOD padlock_rand = { + NULL, /* seed */ + padlock_rand_bytes, /* bytes */ + NULL, /* cleanup */ + NULL, /* add */ + padlock_rand_bytes, /* pseudorand */ + padlock_rand_status, /* rand status */ +}; + +#endif /* COMPILE_HW_PADLOCK */ + +#endif /* !OPENSSL_NO_HW_PADLOCK */ +#endif /* !OPENSSL_NO_HW */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor