Merge pull request #10 from Miceuz/master
[hackover2013-badge-firmware.git] / drivers / rsa / rsa.c
1 /**************************************************************************/
2 /*!
3 @file rsa.c
4 @author Kyle Loudon
5 modified: microBuilder.eu
6 @date 4 January, 2010
7 @version 1.0
8
9 Basic RSA-encryption using 64-bit math (32-bit keys).
10
11 Based on the examples from "Mastering Algorithms with C" by
12 Kyle Loudon (O'Reilly, 1999).
13
14 For details on how to generate a valid RSA key pair, see:
15 http://www.microbuilder.eu/Tutorials/SoftwareDevelopment/RSAEncryption.aspx
16
17 @warning Most versions of libc used for embedded systems do not
18 include support for 64-bit integers with printf, etc. (to
19 keep the compiled code size and memory usage as small as
20 possible). Unless you have explicitly added long long
21 support for printf, you should not try to display 64-bit
22 values with it (%lld, etc.). Using 32-bit values (changing
23 the definition of huge_t to uint32_t) will avoid this issue
24 entirely, though at the expense of weaker encryption.
25 */
26 /**************************************************************************/
27
28 #include "rsa.h"
29
30 huge_t modexp(huge_t a, huge_t b, huge_t n)
31 {
32 huge_t y;
33 y = 1;
34
35 /* Compute pow(a, b) % n using the binary square and multiply method. */
36 while (b != 0)
37 {
38 /* For each 1 in b, accumulate y. */
39 if (b & 1)
40 {
41 y = (y * a) % n;
42 }
43
44 /* Square a for each bit in b. */
45 a = (a * a) % n;
46
47 /* Prepare for the next bit in b. */
48 b = b >> 1;
49 }
50
51 return y;
52 }
53
54 void rsaTest()
55 {
56 huge_t rsaOrig, rsaDecrypted, rsaEncrypted;
57 rsaPubKey_t publicKey;
58 rsaPriKey_t privateKey;
59 int i;
60
61 printf("Encrypting with RSA %s", CFG_PRINTF_NEWLINE);
62
63 #if CFG_RSA_BITS == 64
64 // Values based on 64-bit math (huge_t = uint64_t)
65 // which will result in more secure encryption, but also
66 // increases the size of the encrypted text
67 publicKey.e = 21;
68 publicKey.n = 16484947;
69 privateKey.d = 15689981;
70 privateKey.n = 16484947;
71 #endif
72
73 #if CFG_RSA_BITS == 32
74 // Alternative values with 32-bit math (huge_t = uint32_t)
75 // or when smaller encrypted text is desired
76 publicKey.e = 17;
77 publicKey.n = 209;
78 privateKey.d = 53;
79 privateKey.n = 209;
80 #endif
81
82 #if CFG_RSA_BITS == 64
83 printf("Starting RSA encryption/decryption test %s", CFG_PRINTF_NEWLINE);
84 #endif
85 #if CFG_RSA_BITS == 32
86 printf("d=%u, e=%u, n=%u %s", (unsigned int)privateKey.d, (unsigned int)publicKey.e, (unsigned int)publicKey.n, CFG_PRINTF_NEWLINE);
87 #endif
88
89 for (i = 0; i < 128; i++)
90 {
91 rsaOrig = i;
92 rsaEncrypt(rsaOrig, &rsaEncrypted, publicKey);
93 rsaDecrypt(rsaEncrypted, &rsaDecrypted, privateKey);
94
95 if (rsaOrig == rsaDecrypted)
96 {
97 #if CFG_RSA_BITS == 64
98 printf("Encrypted and decrypted %d %s", i, CFG_PRINTF_NEWLINE);
99 #endif
100 #if CFG_RSA_BITS == 32
101 printf("In=%5u, Encrypted=%5u, Out=%5u (OK) %s", (unsigned int)rsaOrig, (unsigned int)rsaEncrypted, (unsigned int)rsaDecrypted, CFG_PRINTF_NEWLINE);
102 #endif
103 }
104 else
105 {
106 #if CFG_RSA_BITS == 64
107 printf("Failed to decrypt %d %s", i, CFG_PRINTF_NEWLINE);
108 #endif
109 #if CFG_RSA_BITS == 32
110 printf("In=%5u, Encrypted=%5u, Out=%5u (ERROR) %s", (unsigned int)rsaOrig, (unsigned int)rsaEncrypted, (unsigned int)rsaDecrypted, CFG_PRINTF_NEWLINE);
111 #endif
112 }
113 }
114 }
115
116 void rsaEncrypt(huge_t plaintext, huge_t *ciphertext, rsaPubKey_t pubkey)
117 {
118 *ciphertext = modexp(plaintext, pubkey.e, pubkey.n);
119
120 return;
121 }
122
123 void rsaDecrypt(huge_t ciphertext, huge_t *plaintext, rsaPriKey_t prikey)
124 {
125 *plaintext = modexp(ciphertext, prikey.d, prikey.n);
126
127 return;
128 }
This page took 0.060377 seconds and 5 git commands to generate.