3 This file is part of the Crypto-avr-lib/microcrypt-lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * File: serpent_sboxes.S
24 * License: GPLv3 or later
25 * Description: Implementation of the serpent sbox function.
31 /*******************************************************************************
33 *******************************************************************************/
35 .macro push_ p1:req, p2:vararg
42 .macro pop_ p1:req, p2:vararg
49 .macro push_range from:req, to:req
52 push_range "(\from+1)",\to
56 .macro pop_range from:req, to:req
59 pop_range \from,"(\to-1)"
63 .macro stack_alloc size:req, reg1=r30, reg2=r31
64 in r0, _SFR_IO_ADDR(SREG)
66 in \reg1, _SFR_IO_ADDR(SPL)
67 in \reg2, _SFR_IO_ADDR(SPH)
69 out _SFR_IO_ADDR(SPH), \reg2
70 out _SFR_IO_ADDR(SPL), \reg1
71 out _SFR_IO_ADDR(SREG), r0
74 .macro stack_free size:req, reg1=r30, reg2=r31
75 in r0, _SFR_IO_ADDR(SREG)
77 in \reg1, _SFR_IO_ADDR(SPL)
78 in \reg2, _SFR_IO_ADDR(SPH)
80 out _SFR_IO_ADDR(SPH), \reg2
81 out _SFR_IO_ADDR(SPL), \reg1
82 out _SFR_IO_ADDR(SREG), r0
85 /*******************************************************************************
86 * END of MACRO SECTION *
87 *******************************************************************************/
90 static void serpent_lt(uint8_t *b){
176 /* X3 ^= X2 ^ (X0 << 3); */
197 /* X1 = rotl32(X1, 1); */
204 /* X3 = rotl32(X3, 7); */
224 /* X2 ^= X3 ^ (X1 << 7); */
242 /* X0 = rotl32(X0, 5); */
253 /* X2 = rotr32(X2, 10); */
287 /* rotate the data word (4 byte) pointed to by X by r20 bits to the right */
308 /* rotate the data word (4 byte) pointed to by X by r20 bits to the left */
329 /* xor the dataword (4 byte) pointed by Z into X */
342 /* X0 := X0 <<< 13 */
410 /* T := T>>>1; T&=0xfffffff8 */
425 /* X3 := X3 >>> 10 */
438 /* X2 := X2 <<< 10 */
515 /* X0 := X0 >>> 13 */
524 #define GOLDEN_RATIO 0x9e3779b9l
526 static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
528 ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ (uint32_t)i;
529 ret = rotl32(ret, 11);
534 * param b is passed in r24:r25
535 * param i is passed in r22
536 * return value is returned in r22.r23.r24.r25
549 /* ^b[3]^b[5]^[b7] */
592 * void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx)
595 * param key is passed in r24:r25
596 * param keysize is passed in r22:r23
597 * param ctx is passed in r20:r21
616 bst r22, 5 /* store in T if we have to do the "append 1 thing"*/
618 3: /* set buffer to zero */
623 movw r26, r24 /* X points to the key */
626 breq 5f /* if keylength_b==0 */
627 4: /* copy keybytes to buffer */
633 brts 7f /* if keylength_b == 256 */
639 6: /* shift the one to the right position */
645 7: /* post "appending 1 thing" buffer is ready for subkey generation */
646 movw r26, r20 /* X points to the context */
648 pop_ r19, r18 /* r18:r19 points to the buffer */
662 /* store new word in buffer and context */
694 * void serpent_enc(void* buffer, const serpent_ctx_t* ctx){
697 * param buffer is passed in r24:r25
698 * param ctx is passed in r22:r23
703 push_ r12, r13, r14, r15, r16
741 pop_ r16, r15, r14, r13, r12
745 * void serpent_dec(void* buffer, const serpent_ctx_t* ctx){
748 * param buffer is passed in r24:r25
749 * param ctx is passed in r22:r23
753 push_ r12, r13, r14, r15, r16
755 // ldi r16, lo8(32*16)
793 pop_ r16, r15, r14, r13, r12