present80.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* present80.c */
  2. /*
  3. This file is part of the AVR-Crypto-Lib.
  4. Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /**
  17. * present80.c
  18. * a implementation of the PRESENT block-cipher
  19. * author: Daniel Otte
  20. * email: daniel.otte@rub.de
  21. * license: GPLv3
  22. *
  23. * */
  24. #include <string.h>
  25. #include <stdint.h>
  26. #include <crypto/memxor.h>
  27. #include "present_common.h"
  28. #include <crypto/present80.h>
  29. static
  30. void key_update(uint8_t* buffer, uint8_t round){
  31. uint8_t j;
  32. union __attribute__((packed)){
  33. uint8_t v8[2];
  34. uint16_t v16;
  35. } tmp;
  36. /* rotate buffer 19 right */
  37. tmp.v16 = ((uint16_t*)buffer)[4];
  38. j=4;
  39. do{
  40. ((uint16_t*)buffer)[j] = ((uint16_t*)buffer)[j-1];
  41. }while(--j);
  42. ((uint16_t*)buffer)[0] = tmp.v16;
  43. uint8_t t8;
  44. j=0;
  45. t8 = (uint16_t)buffer[9] << (5);
  46. do{
  47. tmp.v8[1] = buffer[j];
  48. tmp.v16 >>= 3;
  49. buffer[j] = tmp.v8[1] | t8;
  50. t8 = tmp.v8[0] & 0xe0;
  51. }while(++j<10);
  52. /* rotating done now substitution */
  53. buffer[0] = (present_sbox(buffer[0])&0xF0) | ((buffer[0])&0x0F);
  54. /* xor with round counter */
  55. buffer[8] ^= round << 7;
  56. buffer[7] ^= round >> 1;
  57. }
  58. static
  59. void key_update_inv(uint8_t* buffer, uint8_t round){
  60. uint8_t j;
  61. union __attribute__((packed)){
  62. uint8_t v8[2];
  63. uint16_t v16;
  64. } tmp;
  65. /* xor with round counter */
  66. buffer[8] ^= round << 7;
  67. buffer[7] ^= round >> 1;
  68. /* rotating done now substitution */
  69. buffer[0] = (present_sbox_inv(buffer[0])&0xF0) | ((buffer[0])&0x0F);
  70. /* rotate buffer 19 left */
  71. tmp.v16 = ((uint16_t*)buffer)[0];
  72. j=0;
  73. do{
  74. ((uint16_t*)buffer)[j] = ((uint16_t*)buffer)[j+1];
  75. }while(++j<4);
  76. ((uint16_t*)buffer)[4] = tmp.v16;
  77. uint8_t t8;
  78. j=9;
  79. t8 = (uint16_t)buffer[0] >> (5);
  80. do{
  81. tmp.v8[0] = buffer[j];
  82. tmp.v16 <<= 3;
  83. buffer[j] = tmp.v8[0] | t8;
  84. t8 = tmp.v8[1] & 0x07;
  85. }while(j--);
  86. }
  87. void present80_init(const uint8_t* key, uint8_t keysize_b, present80_ctx_t* ctx){
  88. uint8_t i;
  89. memcpy(ctx->fwd_key, key, 10);
  90. memcpy(ctx->rev_key, key, 10);
  91. for(i=1; i<32; ++i){
  92. key_update(ctx->rev_key, i);
  93. }
  94. }
  95. void present80_enc(void* buffer, present80_ctx_t* ctx){
  96. present_generic_enc(buffer, (uint8_t*)ctx, 10, key_update);
  97. }
  98. void present80_dec(void* buffer, present80_ctx_t* ctx){
  99. present_generic_dec(buffer, (uint8_t*)ctx, 10, key_update_inv);
  100. }
  101. /*
  102. void present80_enc(void* buffer, present80_ctx_t* ctx){
  103. uint8_t i,j,tmp[8], k[10];
  104. memcpy(k, ctx->fwd_key, 10);
  105. memxor(buffer, k, 8);
  106. for(i=1; i<32; ++i){
  107. j = 7;
  108. do{
  109. tmp[j] = present_sbox(((uint8_t*)buffer)[j]);
  110. }while(j--);
  111. present_p(buffer, tmp);
  112. key_update(k, i);
  113. memxor(buffer, k, 8);
  114. }
  115. }
  116. void present80_dec(void* buffer, present80_ctx_t* ctx){
  117. uint8_t j,tmp[8], k[10];
  118. uint8_t i;
  119. memcpy(k, ctx->rev_key, 10);
  120. memxor(buffer, k, 8);
  121. i = 31;
  122. do{
  123. present_p(tmp, buffer);
  124. present_p(buffer, tmp);
  125. j = 7;
  126. do{
  127. ((uint8_t*)buffer)[j] = sbox_inv(((uint8_t*)buffer)[j]);
  128. }while(j--);
  129. key_update_inv(k, i);
  130. memxor(buffer, k, 8);
  131. }while(--i);
  132. }
  133. */