Commit c095bd83 authored by YUSHIQIAN's avatar YUSHIQIAN

archive for lab 2

parent 1a6b0990
This diff is collapsed.
This diff is collapsed.
CC = gcc
CFLAGS = -Wall -ansi -c -O3
INCLUDES = -I./include
LD = gcc
LDFLAGS =
LIBS =
SRCS = $(wildcard src/*.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
EXECS = dpa
.PHONY: help all clean ultraclean
help:
@echo "Type:"
@echo "<make> or <make help> to get this help message"
@echo "<make all> to compile the dpa executable"
@echo "<make clean> to remove object files"
@echo "<make ultraclean> to remove object files and executable files"
all: $(EXECS)
dpa: dpa.o $(OBJS)
$(LD) $(LDFLAGS) $^ -o $@ $(LIBS) -lm
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@
clean:
rm -f $(OBJS) dpa.o
ultraclean:
rm -f $(OBJS) $(EXECS) dpa.o
This diff is collapsed.
/** \file des.h
* The \b des library, a software library dedicated to the Data Encryption
* Standard (DES).
* \author Renaud Pacalet, renaud.pacalet@telecom-paristech.fr
* \date 2009-07-08
* \attention
* <ol>
* <li>Most functions of the \b des library check their input parameters and
* issue warnings or errors when they carry illegal values. Warnings are
* printed on the standard error output. Errors are also printed on the
* standard error output and the program exits with a -1 exit status.</li>
* <li>The \b des library uses a single data type to represent all the data of
* the DES standard: ::uint64_t. It is a 64 bits unsigned integer.</li>
* <li>Data are always right aligned: when the data width is less than 64 bits,
* the meaningful bits are always the rightmost bits of the ::uint64_t.</li>
* </ol>
*/
#ifndef DES_H
#define DES_H
#include <stdint.h>
#include <inttypes.h>
/** Number of left shifts per round.
* left_shifts[0] corresponds to round #1, ... left_shifts[15] corresponds to
* round #16. A value of 0 means one shift. A value of 1 means two shifts. */
extern uint8_t left_shifts[16];
/** Initial permutation (64 to 64 bits).
* Same as des_n_fp(). \return The permutated input as a 64 bits ::uint64_t. */
uint64_t des_ip (uint64_t val /**< 64 bits input. */ );
/** Inverse of initial permutation (64 to 64 bits).
* Same as des_fp(). \return The permutated input as a 64 bits ::uint64_t. */
uint64_t des_n_ip (uint64_t val /**< 64 bits input. */ );
/** Final permutation (64 to 64 bits).
* Inverse of initial permutation, same as des_n_ip(). \return The permutated
* input as a 64 bits ::uint64_t. */
uint64_t des_fp (uint64_t val /**< 64 bits input. */ );
/** Inverse of final permutation (64 to 64 bits).
* Same as des_ip(). \return The permutated input as a 64 bits ::uint64_t. */
uint64_t des_n_fp (uint64_t val /**< 64 bits input. */ );
/** E expansion - permutation (32 to 48 bits). \return The expanded and
* permutated input as a 48 bits ::uint64_t. */
uint64_t des_e (uint64_t val /**< 32 bits input. */ );
/** Inverse of E expansion - permutation (48 to 32 bits).
* Duplicated bits must have the same value. If they do not, an error is raised.
* \return The permutated and selected input as a 32 bits ::uint64_t. */
uint64_t des_n_e (uint64_t val /**< 48 bits input. */ );
/** P permutation (32 to 32 bits). \return The permutated input as a 32 bits
* ::uint64_t. */
uint64_t des_p (uint64_t val /**< 32 bits input. */ );
/** Inverse of P permutation (32 to 32 bits). \return The permutated input as a
* 32 bits ::uint64_t. */
uint64_t des_n_p (uint64_t val /**< 32 bits input. */ );
/** PC1 permutation - selection (64 to 56 bits).
* No parity check. \return The permutated and selected input as a 56 bits
* ::uint64_t. */
uint64_t des_pc1 (uint64_t val /**< 64 bits input. */ );
/** Computes the 8 parity bits of a 64 bits word.
* Parity bits are the rightmost bit of each byte. Once computed, the number of
* set bits of each byte is odd, as specified in the DES standard. \return The
* input with odd parity bits, as a 64 bits ::uint64_t. */
uint64_t des_set_parity_bits (uint64_t val /**< 64 bits input. */ );
/** Inverse of PC1 permutation - selection (56 to 64 bits).
* Parity bits are computed. \return The permutated and expanded input as a 64
* bits ::uint64_t. */
uint64_t des_n_pc1 (uint64_t val /**< 56 bits input. */ );
/** PC2 permutation - selection (56 to 48 bits). \return The permutated and
* selected input as a 48 bits ::uint64_t. */
uint64_t des_pc2 (uint64_t val /**< 56 bits input. */ );
/** Inverse of PC2 permutation - selection (48 to 56 bits).
* Missing bits are set to 0. \return The permutated and expanded input as a 56
* bits ::uint64_t. */
uint64_t des_n_pc2 (uint64_t val /**< 48 bits input. */ );
/** Single SBox computation (6 to 4 bits). \return The 4 bits output of SBox
* number ::sbox corresponding to the 4 bits input, as a 4 bits
* ::uint64_t. */
uint64_t des_sbox (int sbox /**< SBox number, from 1 to 8. */ ,
uint64_t val
/**< 6 bits input. */
);
/** All SBoxes computation (48 to 32 bits). \return The 32 bits output of all
* SBoxes corresponding to the 48 bits input, as a 32 bits ::uint64_t. */
uint64_t des_sboxes (uint64_t val /**< 48 bits input. */ );
/** Returns the 32 bits right half of a 64 bits word. \return The 32 bits right
* half of a 64 bits word, as a 32 bits ::uint64_t. */
uint64_t des_right_half (uint64_t val /**< 64 bits input. */ );
/** Returns the 32 bits left half of a 64 bits word. \return The 32 bits left
* half of a 64 bits word, as a 32 bits ::uint64_t. */
uint64_t des_left_half (uint64_t val /**< 64 bits input. */ );
/** Applies the <strong>left shift</strong> rotation of the standard (56 to 56
* bits). \return The rotated input, as a 56 bits ::uint64_t. */
uint64_t des_ls (uint64_t val /**< 56 bits input. */ );
/** Applies the <strong>right shift</strong> rotation of the standard (56 to 56
* bits). \return The rotated input, as a 56 bits ::uint64_t. */
uint64_t des_rs (uint64_t val /**< 56 bits input. */ );
/** The F function of the standard (48+32 bits to 32 bits). \return The
* transformed input, as a 32 bits ::uint64_t. */
uint64_t des_f (uint64_t rk /**< 48 bits round key. */ ,
uint64_t val
/**< 32 bits data input. */
);
/** Computes the whole key schedule from a 64 bits secret key and stores the
* sixteen 48 bits round keys in an array. \return The sixteen 48 bits round
* keys in the array passed as first parameter. */
void des_ks (
/** The array where to store the sixteen 48 bits round keys.
* On return \e ks[0] holds the first round key, ..., \e ks[15] holds the
* last round key. Must be allocated prior the call. */
uint64_t * ks, uint64_t val
/**< 64 bits key. */
);
/** Enciphers a 64 bits plaintext with a pre-computed key schedule. \return The
* enciphered plaintext as a 64 bits ::uint64_t. */
uint64_t des_enc (uint64_t * ks /**< The pre-computed key schedule. */ ,
uint64_t val
/**< The 64 bits plaintext. */
);
/** Deciphers a 64 bits plaintext with a pre-computed key schedule. \return The
* deciphered ciphertext as a 64 bits ::uint64_t. */
uint64_t des_dec (uint64_t * ks /**< The pre-computed key schedule. */ ,
uint64_t val
/**< The 64 bits ciphertext. */
);
/** A functional verification of the DES implementation. Runs a number of
* encipherments with des_enc() and the corresponding decipherments with
* des_dec() and checks the results against pre-computed plaintext, ciphertexts
* and secret keys. If compiled in DEBUG mode, prints warnings on mismatches or
* a \b OK message if the tests pass. Returns one on success, zero on errors. */
int des_check (void);
#endif /** not DES_H */
This diff is collapsed.
/**********************************************************************************
Copyright Institut Telecom
Contributors: Renaud Pacalet (renaud.pacalet@telecom-paristech.fr)
This software is a computer program whose purpose is to experiment timing and
power attacks against crypto-processors.
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can use,
modify and/ or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited
liability.
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms. For more
information see the LICENCE-fr.txt or LICENSE-en.txt files.
**********************************************************************************/
/** \file tr_pcc.h
* The \b tr_pcc library, a software library dedicated to the computation of
* Pearson Correlation Coefficients (PCC).
* \author Renaud Pacalet, renaud.pacalet@telecom-paristech.fr
* \date 2009-07-29
*
* Defines a data structure and a set of functions used to compute and manage
* Pearson Correlation Coefficients (PCC) between a floating point (float),
* one-dimension, vector random variable and a set of floating point scalar
* random variables. These coefficients are a statistical tool to evaluate the
* correlation between random variables. In this library, the vectors are
* considered as a collection of scalar floating point random variables and each
* component of the vectors is considered as independant. In the following,
* vectors are denoted Z[.] and the i-th component of vector Z[.] is denoted
* Z[i]. The formula of a PCC between the vector random variable X[.] and the
* scalar random variable Y is:<br>
* PCC(X[.], Y)[.] = {E(X[.]*Y) - E(X[.])*E(Y)[.]} / {s(X[.]) * s(Y)[.]}<br>
* where E(Z) is the expectation (average value) of random variable Z and s(Z)
* is its unbiased standard deviation. E(Z[.])[.] is the expectation vector of
* the vector random variable Z[.]: each component of E(Z[.])[.] is the
* expectation of the corresponding component of Z[.]: E(Z[.])[i] = E(Z[i]).
* Similarly, s(Z[.])[.] is the unbiased standard deviation vector of the vector
* random variable Z[.]: s(Z[.])[i] = s(Z[i]). The product between a vector and
* a scalar is defined as: (X[.]*Y)[i] = X[i]*Y. The PCC between a vector random
* variable X and a scalar random variable Y is a vector defined by:<br>
* PCC(X[.], Y)[i] = PCC(X[i], Y)<br>
* The \b tr_pcc library can be used to compute a set of PCCs between one vector
* random variable (denoted X[.]), common to all PCCs, and a set of scalar
* random variables (denoted Y0, Y1, ..., Yn-1). To compute such a set of PCCs
* one must first initialize a PCC context (tr_pcc_init()), indicating the
* number ny of Y random variables. Then, realizations of the random variables
* must be accumulated into the context: first a realization of the X[.]
* variable (tr_pcc_insert_x()), followed by realizations of each of the ny Y
* variables (tr_pcc_insert_y()). Once a sufficient number of realizations are
* accumulated in the PCC context, a call to tr_pcc_consolidate() computes the
* ny PCCs. Calls to tr_pcc_get_pcc() return the different vector PCCs. Note:
* more realizations can be accumulated after a call to tr_pcc_consolidate(),
* another call to tr_pcc_consolidate() will take them into account altogether
* with the previous ones and compute the new PCC values. A call to
* tr_pcc_free() deallocates the PCC context and makes it reusable for the
* computation of a new set of PCCs. Example of use with 10-components vectors
* and ny=4 Y scalar variables, in which get_next_x and get_next_y are two
* functions returning realizations of the random variables:
* \code
* tr_pcc_context ctx;
* float *x, y, *pcc;
* int i, j, nexp;
* ...
* ctx = tr_pcc_init(10, 4);
* for(i = 0; i < nexp; i++) {
* x = get_next_x();
* tr_pcc_insert_x(ctx, x);
* for(j = 0; j < 4; j++) {
* y = get_next_y(j);
* tr_pcc_insert_y(ctx, j, y);
* }
* }
* tr_pcc_consolidate(ctx);
* for(i = 0; i < 4; i++) {
* pcc = tr_pcc_get_pcc(ctx, j);
printf("PCC(X[.], Y%d)[.] =", i);
* for(j = 0; j < 10; j++)
* printf(" %lf", pcc[j]);
* printf("\n");
* }
* tr_pcc_free(ctx);
* ctx = tr_pcc_init(100, 12);
* ...
* tr_pcc_free(ctx);
* \endcode
* \attention
* It is an error to break the realization insertion scheme: if you initialized
* your PCC context for ny Y variables, first insert a realization of X[.],
* followed by one and only one realization of each of the ny Y variables. Then,
* insert a new realization of X[.] and ny new realizations of the ny Y
* variables, and so on. Consolidate only after inserting the realization of
* the last Y variable. Do not consolidate when in an intermediate state.
* */
#ifndef TR_PCC_H
#define TR_PCC_H
/** The data structure used to compute and manage a set of Pearson correlation
* coefficients. */
struct tr_pcc_context_s
{
int ny; /**< The number of Y random variables. */
int nr; /**< The current number of realizations of the random variables. */
int l; /**< The size of the vector random variable (number of components). */
float *rx; /**< The last inserted realization of X. */
float *x; /**< The sum of the realizations of X. */
float *x2; /**< The sum of the squares of the realizations of X. */
float *y; /**< The array of the sums of the realizations of the Ys. */
float *y2; /**< The array of the sums of the squares of the realizations of the Ys. */
float **xy; /**< The array of the sums of the products between realizations of X and Ys. */
float **pcc; /**< The array of the PCCs. */
char state; /**< Tracker for insertion of the realizations. */
int cnt; /**< Tracker for insertion of the realizations. */
char *flags; /**< Tracker for insertion of the realizations. */
float *tmp1; /**< Temporary trace. */
float *tmp2; /**< Temporary trace. */
float *tmp3; /**< Temporary trace. */
};
/** Pointer to the tr_pcc_context_s data structure. */
typedef struct tr_pcc_context_s *tr_pcc_context;
/** Initializes a PCC context.
* \return An initialized PCC context. */
tr_pcc_context tr_pcc_init (int l,
/**< The length of the X[.] vector random variable (number of components). */
int ny
/**< The number of Y random variables to manage. */
);
/** Insert a realization of X[.] in a PCC context */
void tr_pcc_insert_x (tr_pcc_context ctx, /**< The context */
float *x
/**< The realization of X[.]. */
);
/** Inserts a new Y realization in a PCC context. */
void tr_pcc_insert_y (tr_pcc_context ctx, /**< The context */
int ny,
/**< The index of the Y random variable (0 to ctx->ny - 1). */
float y
/**< The realization of the Y random variable. */ );
/** Consolidates a set of PCCs (computes all the PCCs from the already inserted
* realizations). */
void tr_pcc_consolidate (tr_pcc_context ctx /**< The context */ );
/** Returns a pointer to the PCC vector number ::ny. \return A pointer to the PCC
* vector number ::ny */
float *tr_pcc_get_pcc (tr_pcc_context ctx, /**< The context */
int ny
/**< The index of the PCC to get (0 to ctx->ny - 1). */
);
/** Closes the manager and deallocates it. */
void tr_pcc_free (tr_pcc_context ctx);
#endif /* not TR_PCC_H */
This diff is collapsed.
/**********************************************************************************
Copyright Institut Telecom
Contributors: Renaud Pacalet (renaud.pacalet@telecom-paristech.fr)
This software is a computer program whose purpose is to experiment timing and
power attacks against crypto-processors.
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can use,
modify and/ or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited
liability.
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms. For more
information see the LICENCE-fr.txt or LICENSE-en.txt files.
**********************************************************************************/
/** \file utils.h
* Some utility functions and macros.
*
* When available the macros are much simpler to use, so if they fit your
* needs, do not even look at the functions.
*
* \author Renaud Pacalet, renaud.pacalet@telecom-paristech.fr
* \date 2009-07-08
*/
#ifndef UTILS_H
#define UTILS_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/** Print an error message and exit with -1 status. \e s is the desired exit
* status, followed by a printf-like formating string and an optional
* printf-like variable number of arguments. Example: if file foo.c contains:
* \code
* void bar(void)
* {
* ...
* A = 15;
* ERROR (-1, "invalid value of parameter A: %d", A);
* ...
* }
* \endcode
* and the ERROR macro (at line 47 of foo.c) is executed, it will print the
* message:<br>
\verbatim
*** error in file foo.c, line 47, function bar:
*** invalid value of parameter A: 15
\endverbatim
* on the standard error and then exit with status -1. */
#define ERROR(s,...) error(__FILE__, __LINE__, __func__, (s), __VA_ARGS__)
/** Print a warning message. Takes a printf-like formating string followed by
* an optional printf-like variable number of arguments. Example: if file foo.c
* contains: \code
* void bar(void)
* {
* ...
* A = 15;
* WARNING ("invalid value of parameter A: %d", A);
* ...
* }
* \endcode
* and the WARNING macro (at line 47 of foo.c) is executed, it will print the
* message:<br>
\verbatim
*** warning in file foo.c, line 47, function bar:
*** invalid value of parameter A: 15
\endverbatim
* on the standard error. */
#define WARNING(...) warning(__FILE__, __LINE__, __func__, __VA_ARGS__)
/** Wrapper around the regular malloc memory allocator. Allocates \e n bytes and
* returns a pointer to the allocated memory. Errors are catched, no need to
* check result. \return pointer to allocated memory area. */
#define XMALLOC(n) xmalloc(__FILE__, __LINE__, __func__, (n))
/** Wrapper around the regular calloc memory allocator. Allocates memory for an
* array of \e n elements of \e s bytes each and returns a pointer to the
* allocated memory. Errors are catched, no need to check result. \return
* pointer to allocated memory area. */
#define XCALLOC(n,s) xcalloc(__FILE__, __LINE__, __func__, (n), (s))
/** Wrapper around the regular realloc memory allocator. Resize the memory area
* pointed to py \e p to \e s bytes and returns a pointer to the allocated memory.
* Errors are catched, no need to check result. \return pointer to allocated
* memory area. */
#define XREALLOC(p,s) xrealloc(__FILE__, __LINE__, __func__, (p), (s))
/** Wrapper around the regular fopen. Opens file \e f in mode \e m. Errors are
* catched, no need to check result. \return The FILE pointer to the opened
* file. */
#define XFOPEN(f,m) xfopen(__FILE__, __LINE__, __func__, (f), (m))
/** Returns the Hamming weight of a 64 bits word.
* Note: the input's width can be anything between 0 and 64, as long as the
* unused bits are all zeroes. \return The Hamming weight of the input as a 64
* bits ::uint64_t. */
int hamming_weight (uint64_t val /**< The 64 bits input. */ );
/** Returns the Hamming distance between two 64 bits words.
* Note: the width of the inputs can be anything between 0 and 64, as long as
* they are the same, aligned and that the unused bits are all zeroes. \return
* The Hamming distance between the two inputs as a 64 bits ::uint64_t. */
int hamming_distance (uint64_t val1 /**< The first 64 bits input. */ ,
uint64_t val2
/**< The second 64 bits input. */
);
/** Prints an error message and exit with -1 status.
* Takes a variable number of arguments, as printf. */
void error (const char *file /**< File name. */ ,
const int line /**< Line number. */ ,
const char *fnct /**< Name of calling function. */ ,
const int status /**< Exit status. */ ,
const char *frm, /**< A printf-like formatting string */
... /**< A variable number of arguments. */
);
/** Prints a warning message.
* Takes a variable number of arguments, as printf. */
void warning (const char *file /**< File name. */ ,
const int line /**< Line number. */ ,
const char *fnct /**< Name of calling function. */ ,
const char *frm,
/**< A printf-like formatting string */
.../**< A variable number of arguments. */
);
/** Wrapper around the regular malloc memory allocator. Errors are catched, no
* need to check result. \return pointer to allocated memory area. */
void *xmalloc (const char *file /**< File name. */ ,
const int line /**< Line number. */ ,
const char *fnct /**< Name of calling function. */ ,
const size_t size
/**< Size of an element. */
);
/** Wrapper around the regular calloc memory allocator. Errors are catched, no
* need to check result. \return pointer to allocated memory area. */
void *xcalloc (const char *file /**< File name. */ ,
const int line /**< Line number. */ ,
const char *fnct /**< Name of calling function. */ ,
const size_t nmemb /**< Number of elements to allocate. */ ,
const size_t size /**< Size of an element. */
);
/** Wrapper around the regular realloc memory allocator. Errors are catched, no
* need to check result. \return pointer to allocated memory area. */
void *xrealloc (const char *file /**< File name. */ ,
const int line /**< Line number. */ ,
const char *fnct /**< Name of calling function. */ ,
void *ptr /**< Source pointer. */ ,
const size_t size /**< Size of new memory area. */
);
/** Wrapper around the regular fopen. Errors are catched, no
* need to check result. \return The FILE pointer to the opened file. */
FILE *xfopen (const char *file /**< File name. */ ,
const int line /**< Line number. */ ,
const char *fnct /**< Name of calling function. */ ,
const char *name /**< File name */ ,
const char *mode
/**< Mode */
);
#endif /** not UTILS_H */
This diff is collapsed.
/**********************************************************************************
Copyright Institut Telecom
Contributors: Renaud Pacalet (renaud.pacalet@telecom-paristech.fr)
This software is a computer program whose purpose is to experiment timing and
power attacks against crypto-processors.
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can use,
modify and/ or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited
liability.
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms. For more
information see the LICENCE-fr.txt or LICENSE-en.txt files.
**********************************************************************************/
#include <stdlib.h>
#include <utils.h>
#include <des.h>
#include <km.h>
des_key_manager
des_km_init (void)
{
des_key_manager km;
km = XCALLOC (1, sizeof (struct des_key_manager_s));
km->mask = UINT64_C (0x0);
km->key = UINT64_C (0x0);
return km;
}
int
des_km_known (des_key_manager km)
{
return hamming_weight(km->mask);
}
int
des_km_set_sk (des_key_manager km, int rk, int sk, int force, uint64_t mask,
uint64_t val)
{
if ((sk < 1) || (sk > 8))
{
ERROR (-1, "illegal subkey number: %d", sk);
}
if (mask >> 6)
{
ERROR (-1, "illegal mask value: %016" PRIx64, mask);
}
if (val >> 6)
{
ERROR (-1, "illegal subkey value: %016" PRIx64, val);
}
mask <<= 6 * (8 - sk);
val <<= 6 * (8 - sk);
return des_km_set_rk (km, rk, force, mask, val);
}
int
des_km_set_rk (des_key_manager km, int rk, int force, uint64_t mask,
uint64_t val)
{
int i;
if ((rk < 1) || (rk > 16))
{
ERROR (-1, "illegal round key number: %d", rk);
}
if (mask >> 48)
{
ERROR (-1, "illegal mask value: %016" PRIx64, mask);
}
if (val >> 48)
{
ERROR (-1, "illegal subkey value: %016" PRIx64, val);
}
mask = des_n_pc2 (mask);
val = des_n_pc2 (val);
for (i = rk; i < 16; i++)
{
mask = des_ls (mask);
val = des_ls (val);
if (left_shifts[i] == 1)
{
mask = des_ls (mask);
val = des_ls (val);
}
}
return des_km_set_c0d0 (km, force, mask, val);
}
uint64_t
des_km_set_c0d0 (des_key_manager km, int force, uint64_t mask, uint64_t val)
{
uint64_t conflict;
if (mask >> 56)
{
ERROR (-1, "illegal mask value: %016" PRIx64, mask);
}
if (val >> 56)
{
ERROR (-1, "illegal subkey value: %016" PRIx64, val);
}
val &= mask;
conflict = (km->key ^ val) & km->mask & mask;
if ((conflict == UINT64_C (0x0)) || force)
{
km->mask |= mask;
km->key = (km->key & (~mask)) | val;
}
return (conflict == UINT64_C (0x0)) ? UINT64_C (0x1) : UINT64_C (0x0);
}
int
des_km_set_key (des_key_manager km, int force, uint64_t mask, uint64_t val)
{
mask = des_pc1 (mask);
val = des_pc1 (val);
return des_km_set_c0d0 (km, force, mask, val);
}
uint64_t
des_km_get_sk (des_key_manager km, int rk, int sk, uint64_t * mask)
{
uint64_t val;
if ((sk < 1) || (sk > 8))
{
ERROR (-1, "illegal subkey number: %d", sk);
}
val = des_km_get_rk (km, rk, mask);
*mask = ((*mask) >> (6 * (8 - sk))) & UINT64_C (0x3f);
val = (val >> (6 * (8 - sk))) & UINT64_C (0x3f);
return val;
}
uint64_t
des_km_get_rk (des_key_manager km, int rk, uint64_t * mask)
{
uint64_t val;
int i;
if ((rk < 1) || (rk > 16))
{
ERROR (-1, "illegal round key number: %d", rk);
}
val = des_km_get_c0d0 (km, mask);
for (i = 0; i < rk; i++)
{
*mask = des_ls (*mask);
val = des_ls (val);
if (left_shifts[i] == 1)
{
*mask = des_ls (*mask);
val = des_ls (val);
}
}
*mask = des_pc2 (*mask);
val = des_pc2 (val);
return val;
}
uint64_t
des_km_get_c0d0 (des_key_manager km, uint64_t * mask)