Annotation of embedaddon/strongswan/src/libstrongswan/plugins/padlock/padlock_rng.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008 Martin Willi
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "padlock_rng.h"
                     17: 
                     18: typedef struct private_padlock_rng_t private_padlock_rng_t;
                     19: typedef enum padlock_quality_factor_t padlock_quality_factor_t;
                     20: 
                     21: /**
                     22:  * Padlock RNG quality factors
                     23:  */
                     24: enum padlock_quality_factor_t {
                     25:        /* Lowest quality: Reads 8 bytes */
                     26:        PADLOCK_QF0 = 0x00,
                     27:        /* Medium quality: Reads 4 bytes */
                     28:        PADLOCK_QF1 = 0x01,
                     29:        /* Better quality: Reads 2 bytes */
                     30:        PADLOCK_QF2 = 0x10,
                     31:        /* Highest quality: Reads 1 byte */
                     32:        PADLOCK_QF3 = 0x11,
                     33: };
                     34: 
                     35: /**
                     36:  * Private data of an padlock_rng_t object.
                     37:  */
                     38: struct private_padlock_rng_t {
                     39: 
                     40:        /**
                     41:         * Public padlock_rng_t interface.
                     42:         */
                     43:        padlock_rng_t public;
                     44: 
                     45:        /**
                     46:         * Padlock quality factor
                     47:         */
                     48:        padlock_quality_factor_t quality;
                     49: };
                     50: 
                     51: /**
                     52:  * Get bytes from Padlock RNG. buf should have space for (len + 7)
                     53:  */
                     54: static void rng(char *buf, int len, int quality)
                     55: {
                     56:        while (len > 0)
                     57:        {
                     58:                int status;
                     59: 
                     60:                /* run XSTORE until we have all bytes needed. We do not use REP, as
                     61:                 * this should not be performance critical and it's easier this way. */
                     62:                asm volatile (
                     63:                        ".byte 0x0F,0xA7,0xC0 \n\t"
                     64:                        : "=D"(buf), "=a"(status)
                     65:                        : "d"(quality), "D"(buf));
                     66: 
                     67:                /* bits[0..4] of status word contains the number of bytes read */
                     68:                len -= status & 0x1F;
                     69:        }
                     70: }
                     71: 
                     72: METHOD(rng_t, allocate_bytes, bool,
                     73:        private_padlock_rng_t *this, size_t bytes, chunk_t *chunk)
                     74: {
                     75:        chunk->len = bytes;
                     76:        /* padlock requires some additional bytes */
                     77:        chunk->ptr = malloc(bytes + 7);
                     78: 
                     79:        rng(chunk->ptr, chunk->len, this->quality);
                     80:        return TRUE;
                     81: }
                     82: 
                     83: METHOD(rng_t, get_bytes, bool,
                     84:        private_padlock_rng_t *this, size_t bytes, uint8_t *buffer)
                     85: {
                     86:        chunk_t chunk;
                     87: 
                     88:        /* Padlock needs a larger buffer than "bytes", we need a new buffer */
                     89:        allocate_bytes(this, bytes, &chunk);
                     90:        memcpy(buffer, chunk.ptr, bytes);
                     91:        chunk_clear(&chunk);
                     92:        return TRUE;
                     93: }
                     94: 
                     95: METHOD(rng_t, destroy, void,
                     96:        private_padlock_rng_t *this)
                     97: {
                     98:        free(this);
                     99: }
                    100: 
                    101: /*
                    102:  * Described in header.
                    103:  */
                    104: padlock_rng_t *padlock_rng_create(rng_quality_t quality)
                    105: {
                    106:        private_padlock_rng_t *this;
                    107: 
                    108:        INIT(this,
                    109:                .public = {
                    110:                        .rng = {
                    111:                                .get_bytes = _get_bytes,
                    112:                                .allocate_bytes = _allocate_bytes,
                    113:                                .destroy = _destroy,
                    114:                        },
                    115:                },
                    116:        );
                    117: 
                    118:        /* map RNG quality to Padlock quality factor */
                    119:        switch (quality)
                    120:        {
                    121:                case RNG_WEAK:
                    122:                        this->quality = PADLOCK_QF0;
                    123:                        break;
                    124:                case RNG_STRONG:
                    125:                        this->quality = PADLOCK_QF1;
                    126:                        break;
                    127:                case RNG_TRUE:
                    128:                        this->quality = PADLOCK_QF3;
                    129:                        break;
                    130:                default:
                    131:                        free(this);
                    132:                        return NULL;
                    133:        }
                    134:        return &this->public;
                    135: }
                    136: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>