From: bg Date: Wed, 18 Apr 2012 01:05:24 +0000 (+0000) Subject: some fixes, mainly at rsaes-pkcs1v15 X-Git-Url: https://git.cryptolib.org/?p=avr-crypto-lib.git;a=commitdiff_plain;h=cc6b183296a5852449e3324737e2a2dece788786 some fixes, mainly at rsaes-pkcs1v15 --- diff --git a/Makefile_main.inc b/Makefile_main.inc index 9a3f05f..9ace98f 100644 --- a/Makefile_main.inc +++ b/Makefile_main.inc @@ -34,8 +34,7 @@ GLOBAL_INCDIR := ./ $(TESTSRC_DIR) #------------------------------------------------------------------------------- # inclusion of make stubs -include mkfiles/0*.mk -include mkfiles/*.mk +include $(sort $(wildcard mkfiles/*.mk)) #------------------------------------------------------------------------------- ALGORITHMS = $(BLOCK_CIPHERS) $(STREAM_CIPHERS) $(HASHES) $(PRNGS) $(MACS) \ diff --git a/Makefile_sys_conf.inc b/Makefile_sys_conf.inc index bf7702a..b617523 100644 --- a/Makefile_sys_conf.inc +++ b/Makefile_sys_conf.inc @@ -27,7 +27,7 @@ STAT_DIR = stats/$(BOARD_NAME)/# AUTOASM_DIR = autoasm/$(BOARD_NAME)/# AUTOASM_OPT = -S CC = avr-gcc -CSTD = c99 +CSTD = gnu99 SIZESTAT_FILE = sizestats.txt diff --git a/bigint/bigint.c b/bigint/bigint.c index 6db0389..c69d42e 100644 --- a/bigint/bigint.c +++ b/bigint/bigint.c @@ -291,26 +291,34 @@ int8_t bigint_cmp_u(const bigint_t* a, const bigint_t* b){ void bigint_add_s(bigint_t* dest, const bigint_t* a, const bigint_t* b){ uint8_t s; + int8_t d = 0; s = GET_SIGN(a)?2:0; s |= GET_SIGN(b)?1:0; switch(s){ case 0: /* both positive */ + d = 1; bigint_add_u(dest, a,b); - SET_POS(dest); break; case 1: /* a positive, b negative */ + d = bigint_cmp_u(a,b); bigint_sub_u(dest, a, b); break; case 2: /* a negative, b positive */ + d = bigint_cmp_u(b,a); bigint_sub_u(dest, b, a); break; case 3: /* both negative */ + d = -1; bigint_add_u(dest, a, b); - SET_NEG(dest); break; default: /* how can this happen?*/ break; } + if(d<0){ + SET_NEG(dest); + }else{ + SET_POS(dest); + } } /******************************************************************************/ diff --git a/blake/blake_large.c b/blake/blake_large.c index eb6511c..9dc118b 100644 --- a/blake/blake_large.c +++ b/blake/blake_large.c @@ -146,21 +146,24 @@ void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* msg, uint16_t len msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B; length_b -= BLAKE_LARGE_BLOCKSIZE; } - uint8_t buffer[128]; + union { + uint8_t v8[128]; + uint64_t v64[ 16]; + } buffer; uint64_t v[16]; uint64_t ctr; ctr = ctx->counter*1024+length_b; - memset(buffer, 0, 128); - memcpy(buffer, msg, (length_b+7)/8); - buffer[length_b/8] |= 0x80 >> (length_b&0x7); - blake_large_changeendian(buffer, buffer); + memset(buffer.v8, 0, 128); + memcpy(buffer.v8, msg, (length_b+7)/8); + buffer.v8[length_b/8] |= 0x80 >> (length_b&0x7); + blake_large_changeendian(buffer.v8, buffer.v8); blake_large_expand(v, ctx); if(length_b>1024-128-2){ v[12] ^= ctr; v[13] ^= ctr; - blake_large_compress(v, buffer); + blake_large_compress(v, buffer.v8); blake_large_collapse(ctx, v); - memset(buffer, 0, 128-8); + memset(buffer.v8, 0, 128-8); blake_large_expand(v, ctx); } else { if(length_b){ @@ -169,9 +172,9 @@ void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* msg, uint16_t len } } if(ctx->appendone) - buffer[128-16-8] |= 0x01; - *((uint64_t*)(&(buffer[128-8]))) = ctr; - blake_large_compress(v, buffer); + buffer.v8[128-16-8] |= 0x01; + buffer.v64[15] = ctr; + blake_large_compress(v, buffer.v8); blake_large_collapse(ctx, v); } diff --git a/blake/blake_small.c b/blake/blake_small.c index cc3f6d2..fafea39 100644 --- a/blake/blake_small.c +++ b/blake/blake_small.c @@ -141,26 +141,29 @@ void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* msg, uint16_t len msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B; length_b -= BLAKE_SMALL_BLOCKSIZE; } - uint8_t buffer[64]; + union { + uint8_t v8[64]; + uint32_t v32[16]; + } buffer; uint32_t v[16]; union { uint64_t v64; uint32_t v32[2]; }ctr; ctr.v64 = ctx->counter*512+length_b; - memset(buffer, 0, 64); - memcpy(buffer, msg, (length_b+7)/8); - buffer[length_b/8] |= 0x80 >> (length_b&0x7); - blake_small_changeendian(buffer, buffer); + memset(buffer.v8, 0, 64); + memcpy(buffer.v8, msg, (length_b+7)/8); + buffer.v8[length_b/8] |= 0x80 >> (length_b&0x7); + blake_small_changeendian(buffer.v8, buffer.v8); blake_small_expand(v, ctx); if(length_b>512-64-2){ v[12] ^= ctr.v32[0]; v[13] ^= ctr.v32[0]; v[14] ^= ctr.v32[1]; v[15] ^= ctr.v32[1]; - blake_small_compress(v, buffer); + blake_small_compress(v, buffer.v8); blake_small_collapse(ctx, v); - memset(buffer, 0, 64-8); + memset(buffer.v8, 0, 64-8); blake_small_expand(v, ctx); }else{ if(length_b){ @@ -171,10 +174,10 @@ void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* msg, uint16_t len } } if(ctx->appendone) - buffer[64-8-4] |= 0x01; - *((uint32_t*)(&(buffer[64-8]))) = ctr.v32[1]; - *((uint32_t*)(&(buffer[64-4]))) = ctr.v32[0]; - blake_small_compress(v, buffer); + buffer.v8[64-8-4] |= 0x01; + buffer.v32[14] = ctr.v32[1]; + buffer.v32[15] = ctr.v32[0]; + blake_small_compress(v, buffer.v8); blake_small_collapse(ctx, v); } diff --git a/bmw/bmw_large.c b/bmw/bmw_large.c index 4b2b768..45a449f 100644 --- a/bmw/bmw_large.c +++ b/bmw/bmw_large.c @@ -523,33 +523,36 @@ void bmw_large_nextBlock(bmw_large_ctx_t* ctx, const void* block){ } void bmw_large_lastBlock(bmw_large_ctx_t* ctx, const void* block, uint16_t length_b){ - uint8_t buffer[128]; + union { + uint8_t v8[128]; + uint64_t v64[ 16]; + } buffer; while(length_b >= BMW_LARGE_BLOCKSIZE){ bmw_large_nextBlock(ctx, block); length_b -= BMW_LARGE_BLOCKSIZE; block = (uint8_t*)block + BMW_LARGE_BLOCKSIZE_B; } - memset(buffer, 0, 128); - memcpy(buffer, block, (length_b+7)/8); - buffer[length_b>>3] |= 0x80 >> (length_b&0x07); + memset(buffer.v8, 0, 128); + memcpy(buffer.v8, block, (length_b+7)/8); + buffer.v8[length_b>>3] |= 0x80 >> (length_b&0x07); if(length_b+1>128*8-64){ - bmw_large_nextBlock(ctx, buffer); - memset(buffer, 0, 128-8); + bmw_large_nextBlock(ctx, buffer.v8); + memset(buffer.v8, 0, 128-8); ctx->counter -= 1; } - *((uint64_t*)&(buffer[128-8])) = (uint64_t)(ctx->counter*1024LL)+(uint64_t)length_b; - bmw_large_nextBlock(ctx, buffer); + buffer.v64[15] = (uint64_t)(ctx->counter*1024LL)+(uint64_t)length_b; + bmw_large_nextBlock(ctx, buffer.v8); #if TWEAK uint8_t i; uint64_t q[32]; - memset(buffer, 0xaa, 128); + memset(buffer.v8, 0xaa, 128); for(i=0; i<16; ++i){ - buffer[8*i] = i + 0xa0; + buffer.v8[8*i] = i + 0xa0; } - bmw_large_f0(q, (uint64_t*)buffer, ctx->h); - bmw_large_f1(q, ctx->h, (uint64_t*)buffer); - bmw_large_f2((uint64_t*)buffer, q, ctx->h); - memcpy(ctx->h, buffer, 128); + bmw_large_f0(q, buffer.v64, ctx->h); + bmw_large_f1(q, ctx->h, buffer.v64); + bmw_large_f2(buffer.v64, q, ctx->h); + memcpy(ctx->h, buffer.v8, 128); #endif } diff --git a/bmw/bmw_small.c b/bmw/bmw_small.c index b7013f3..b41e923 100644 --- a/bmw/bmw_small.c +++ b/bmw/bmw_small.c @@ -499,38 +499,42 @@ void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block){ } void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b){ - uint8_t buffer[64]; + union { + uint8_t v8[64]; + uint32_t v32[16]; + uint64_t v64[ 8]; + } buffer; while(length_b >= BMW_SMALL_BLOCKSIZE){ bmw_small_nextBlock(ctx, block); length_b -= BMW_SMALL_BLOCKSIZE; block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B; } - memset(buffer, 0, 64); - memcpy(buffer, block, (length_b+7)/8); - buffer[length_b>>3] |= 0x80 >> (length_b&0x07); + memset(buffer.v8, 0, 64); + memcpy(buffer.v8, block, (length_b+7)/8); + buffer.v8[length_b>>3] |= 0x80 >> (length_b&0x07); if(length_b+1>64*8-64){ - bmw_small_nextBlock(ctx, buffer); - memset(buffer, 0, 64-8); + bmw_small_nextBlock(ctx, buffer.v8); + memset(buffer.v8, 0, 64-8); ctx->counter -= 1; } - *((uint64_t*)&(buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b; - bmw_small_nextBlock(ctx, buffer); + buffer.v64[7] = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b; + bmw_small_nextBlock(ctx, buffer.v8); #if TWEAK uint8_t i; uint32_t q[32]; - memset(buffer, 0xaa, 64); + memset(buffer.v8, 0xaa, 64); for(i=0; i<16;++i){ - buffer[i*4] = i+0xa0; + buffer.v8[i*4] = i+0xa0; } -// dump_x(buffer, 16, 'A'); +// dump_x(buffer.v8, 16, 'A'); dump_x(ctx->h, 16, 'M'); - bmw_small_f0(q, (uint32_t*)buffer, ctx->h); - dump_x(buffer, 16, 'a'); + bmw_small_f0(q, buffer.v32, ctx->h); + dump_x(buffer.v8, 16, 'a'); dump_x(q, 16, 'Q'); - bmw_small_f1(q, ctx->h, (uint32_t*)buffer); + bmw_small_f1(q, ctx->h, buffer.v32); dump_x(q, 32, 'Q'); - bmw_small_f2((uint32_t*)buffer, q, ctx->h); - memcpy(ctx->h, buffer, 64); + bmw_small_f2(buffer.v32, q, ctx->h); + memcpy(ctx->h, buffer.v8, 64); #endif } diff --git a/host/rsa_pkcs15_check.rb b/host/rsa_pkcs15_check.rb deleted file mode 100644 index cdafa8a..0000000 --- a/host/rsa_pkcs15_check.rb +++ /dev/null @@ -1,390 +0,0 @@ -#!/usr/bin/ruby -# rsa_pkcs15_check.rb -=begin - This file is part of the AVR-Crypto-Lib. - Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -=end - -require 'rubygems' -require 'serialport' -require 'getopt/std' - -$buffer_size = 0 # set automatically in init_system -$conffile_check = Hash.new -$conffile_check.default = 0 -$debug = false -$logfile = nil - -################################################################################ -# readconfigfile # -################################################################################ - -def read_line_from_device() - repeat_counter = 10000 - l = nil - s = '' - begin - l = $sp.gets() - repeat_counter -= 1 - end while !l && repeat_counter > 0 - t = Time.new - $logfile.printf("DBG: (%02d:%02d:%02d)<< %s\n", t.hour, t.min, t.sec, l.inspect) if $debug - if l && l.include?("AVR-Crypto-Lib") - $logfile.printf("DBG: system crashed !!!\n") - exit(false) - end - return l -end - -def readconfigfile(fname, conf) - return conf if $conffile_check[fname]==1 - $conffile_check[fname]=1 - section = "default" - if not File.exists?(fname) - return conf - end - file = File.open(fname, "r") - until file.eof - line = file.gets() - next if /[\s]*#/.match(line) - if m=/\[[\s]*([^\s]*)[\s]*\]/.match(line) - section=m[1] - conf[m[1]] = Hash.new - next - end - next if ! /=/.match(line) - m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line) - if m[1]=="include" - Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) } - else - conf[section][m[1]] = m[2] - end - end - file.close() - return conf -end - -################################################################################ -# reset_system # -################################################################################ - -def reset_system - $sp.print("\r") - sleep 0.1 - $sp.print("\r") - sleep 0.1 - $sp.print("echo off\r") - sleep 0.1 -end - - -def read_block(f) - d = Array.new - begin - l = f.gets - x = l.split.collect { |e| e.to_i(16) } - d += x - end while x.length == 16 - return d -end - -=begin -# Modulus: -# Exponent: -# Modulus: -# Public exponent: -# Exponent: -# Prime 1: -# Prime 2: -# Prime exponent 1: -# Prime exponent 2: -# Coefficient: -# Message: -# Seed: -# Encryption: - -=end - -def get_next_block(f) - ret = Hash.new - data = Array.new - begin - l = f.gets - end while l && ! m= l.match(/^#[\s](.*):[\s]*$/) - return nil if ! l - ret['tag'] = m[1] - ret['line'] = f.lineno - data = read_block(f) - ret['data'] = data - return ret -end - -$key_sequence = [ - 'Modulus', # 0 - 'Exponent', # 1 - 'Modulus', # 2 - 'Public exponent', # 3 - 'Exponent', # 4 - 'Prime 1', # 5 - 'Prime 2', # 6 - 'Prime exponent 1', # 7 - 'Prime exponent 2', # 8 - 'Coefficient', # 9 -] - -def key_consitency_check(k) - return true -end - -def process_file(f, skip_key=1, skip_vec=1) - a = get_next_block(f) - key_no = 0 - ok_counter = 0 - fail_counter = 0 - begin - if !a || ! a['tag'] == 'Modulus' - printf("ERROR: a = %s %d\n", a.inspect, __LINE__) - return - end - k_seq = Array.new - k_seq[0] = a - (1..($key_sequence.length-1)).each do |i| - a = get_next_block(f) - if ! a || a['tag'] != $key_sequence[i] - printf("ERROR: (expecting: %s) a = %s %d\n", $key_sequence[i], a.inspect, __LINE__) - end - k_seq[i] = a - end - key = convert_key(k_seq) - printf("ERROR: %d\n", __LINE__) if ! key - key_no += 1 - vec_no = 0 - printf("\n run %3d: ", key_no) - skip_key_flag = (key_no < skip_key) - load_key(key) if ! skip_key_flag - test_seq = Array.new - a = get_next_block(f) - printf("ERROR: %d\n", __LINE__) if ! a - begin - vec_no += 1 - b = get_next_block(f) - c = get_next_block(f) - tv = Hash.new - tv['msg'] = a['data'] - tv['seed'] = b['data'] - tv['enc'] = c['data'] - skip_vec_flag = (skip_key_flag || (key_no == skip_key && vec_no < skip_vec)) - if skip_vec_flag - printf('o') - else - v = check_tv(tv) - if(v == true) - printf('*') - $logfile.printf("[[Test %2d.%02d = OK]]\n", key_no, vec_no) - ok_counter += 1 - else - printf('%c', v ? '*' : '!') - $logfile.printf("[[Test %2d.%02d = FAIL]]\n", key_no, vec_no) - fail_counter += 1 - end - end - a = get_next_block(f) - end while a && a['tag'] == 'Message' - end while a && a['tag'] = 'Modulus' -# printf("\nResult: %d OK / %d FAIL ==> %s \nFinished\n", ok_counter, fail_counter, fail_counter==0 ? ':-)' : ':-(') - return ok_counter,fail_counter -end - -def convert_key(k_seq) - l = ['n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv'] - r = Hash.new - return nil if k_seq[0]['data'] != k_seq[2]['data'] - return nil if k_seq[1]['data'] != k_seq[3]['data'] - 8.times do |i| - r[l[i]] = k_seq[2 + i]['data'] - end - return r -end - -def wait_for_dot - begin - s = $sp.gets() - end while !s || !s.include?('.') -end - -def load_bigint(d) - $sp.printf("%d\r", d.length) - while l = read_line_from_device() - break if /data:/.match(l) - end - printf "ERROR: got no answer from system!" if !l - i = 0 - d.each do |e| - $sp.printf("%02x", e) - i += 1 - if i % 60 == 0 -# we should now wait for incomming dot - wait_for_dot() - print('.') - end - end -end - -def hexdump(a) - i = 0 - a.each do |e| - printf("\n\t") if i % 16 == 0 - printf('%02x ', e) - i += 1 - end - puts('') if i % 16 != 1 -end - -def str_hexdump(a) - i = 0 - s = '' - a.each do |e| - s += "\n\t" if i % 16 == 0 - s += sprintf('%02x ', e) - i += 1 - end - s += "\n" if i % 16 != 1 - return s -end - -def load_key(k) - $sp.print("load-key\r") - sleep 0.1 - v = ['n', 'e', 'p', 'q', 'dP', 'dQ', 'qInv'] - v.each do |e| - load_bigint(k[e]) - $logfile.printf("DBG: loaded %s\n", e) if $debug - end - while l = read_line_from_device() - break if />/.match(l) - end -end - -def strip_leading_zeros(a) - loop do - return [] if a.length == 0 - return a if a[0] != 0 - a.delete_at(0) - end -end - -def check_tv(tv) - sleep 0.1 - $sp.print("seed-test\r") - sleep 0.1 - load_bigint(tv['msg']) - $logfile.printf("DBG: loaded %s\n", 'msg') if $debug - sleep 0.1 - tv['seed'].each { |e| $sp.printf(" %02x", e) } - while l = read_line_from_device() - break if /ciphertext:/.match(l) - end - test_enc = '' - loop do - l = read_line_from_device() - break if ! /([0-9A-Fa-f]{2}\s*)+/.match(l) - test_enc += l if l - end - test_enc_a = Array.new - test_enc = test_enc.split(/[\W\r\n]+/) - test_enc.each do |e| - v = e.sub(/[^0-9A-Fa-f]/, '') - test_enc_a << v if v.length == 2 - end - test_enc_a.collect!{ |e| e.to_i(16) } - strip_leading_zeros(test_enc_a) - strip_leading_zeros(tv['enc']) - enc_ok = (test_enc_a == tv['enc']) - if !enc_ok - $logfile.printf("DBG: ref = %s test = %s\n", str_hexdump(tv['enc']) , str_hexdump(test_enc_a)) - end - m = nil - loop do - l = read_line_from_device() - m = /(>>OK<<|ERROR)/.match(l) - break if m - end - return true if enc_ok && (m[1] == '>>OK<<') - return false -end - -######################################## -# MAIN -######################################## - - -opts = Getopt::Std.getopts('dc:f:il:s:') - -conf = Hash.new -conf = readconfigfile("/etc/testport.conf", conf) -conf = readconfigfile("~/.testport.conf", conf) -conf = readconfigfile("testport.conf", conf) -conf = readconfigfile(opts["c"], conf) if opts["c"] - -#puts conf.inspect - -puts("serial port interface version: " + SerialPort::VERSION); -$linewidth = 64 -params = { "baud" => conf["PORT"]["baud"].to_i, - "data_bits" => conf["PORT"]["databits"].to_i, - "stop_bits" => conf["PORT"]["stopbits"].to_i, - "parity" => SerialPort::NONE } -params["paraty"] = SerialPort::ODD if conf["PORT"]["paraty"].downcase == "odd" -params["paraty"] = SerialPort::EVEN if conf["PORT"]["paraty"].downcase == "even" -params["paraty"] = SerialPort::MARK if conf["PORT"]["paraty"].downcase == "mark" -params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space" - -puts("\nPort: "+conf["PORT"]["port"]+"@" + - params["baud"].to_s + - " " + - params["data_bits"].to_s + - conf["PORT"]["paraty"][0,1].upcase + - params["stop_bits"].to_s + - "\n") - -$sp = SerialPort.new(conf["PORT"]["port"], params) - -$sp.read_timeout=1000; # 5 minutes -$sp.flow_control = SerialPort::SOFT - -$debug = true if opts['d'] - -if opts['l'] - $logfile = File.open(opts['l'], 'w') -end - -$logfile = STDOUT if ! $logfile -reset_system() - -if opts['s'] && m = opts['s'].match(/([\d]+\.([\d]+))/) - sk = m[1].to_i - sv = m[2].to_i -else - sk = 1 - sv = 1 -end - -f = File.open(opts['f'], "r") -exit if !f -ok,fail = process_file(f,sk,sv) -printf("\nOK: %d FAIL: %d :-%s\n",ok,fail, fail==0 ? ')':'(') - - diff --git a/host/rsa_pkcs1v15_check.rb b/host/rsa_pkcs1v15_check.rb new file mode 100644 index 0000000..c8d51a6 --- /dev/null +++ b/host/rsa_pkcs1v15_check.rb @@ -0,0 +1,425 @@ +#!/usr/bin/ruby +# rsa_pkcs1v15_check.rb +=begin + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +=end + +require 'rubygems' +require 'serialport' +require 'getopt/std' +require 'fileutils' + +$buffer_size = 0 # set automatically in init_system +$conffile_check = Hash.new +$conffile_check.default = 0 +$debug = false +$logfile = nil + +################################################################################ +# readconfigfile # +################################################################################ + +def read_line_from_device() + repeat_counter = 10000 + l = nil + s = '' + begin + l = $sp.gets() + repeat_counter -= 1 + end while !l && repeat_counter > 0 + t = Time.new + $logfile.printf("DBG: (%02d:%02d:%02d)<< %s\n", t.hour, t.min, t.sec, l.inspect) if $debug + if l && l.include?("AVR-Crypto-Lib") + $logfile.printf("DBG: system crashed !!!\n") + exit(false) + end + return l +end + +def readconfigfile(fname, conf) + return conf if $conffile_check[fname]==1 + $conffile_check[fname]=1 + section = "default" + if not File.exists?(fname) + return conf + end + file = File.open(fname, "r") + until file.eof + line = file.gets() + next if /[\s]*#/.match(line) + if m=/\[[\s]*([^\s]*)[\s]*\]/.match(line) + section=m[1] + conf[m[1]] = Hash.new + next + end + next if ! /=/.match(line) + m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line) + if m[1]=="include" + Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) } + else + conf[section][m[1]] = m[2] + end + end + file.close() + return conf +end + +################################################################################ +# reset_system # +################################################################################ + +def reset_system + $sp.print("\r") + sleep 0.1 + $sp.print("\r") + sleep 0.1 + $sp.print("echo off\r") + sleep 0.1 +end + + +def read_block(f) + d = Array.new + begin + v = false + l = f.gets + # x = l.split.collect { |e| e.to_i(16) } + t = l.split + t.each { |e| v = true if e.length != 2 } + x = [] + x = t.collect { |e| e.to_i(16) } if ! v + d += x + end while x.length == 16 && ! v + return d +end + +=begin +# Modulus: +# Exponent: +# Modulus: +# Public exponent: +# Exponent: +# Prime 1: +# Prime 2: +# Prime exponent 1: +# Prime exponent 2: +# Coefficient: +# Message: +# Seed: +# Encryption: + +=end + +def get_next_block(f) + ret = Hash.new + data = Array.new + begin + l = f.gets + end while l && ! m= l.match(/^#[\s](.*):[\s]*$/) + return nil if ! l + ret['tag'] = m[1] + ret['line'] = f.lineno + data = read_block(f) + ret['data'] = data + return ret +end + +$key_sequence = [ + 'Modulus', # 0 + 'Exponent', # 1 + 'Modulus', # 2 + 'Public exponent', # 3 + 'Exponent', # 4 + 'Prime 1', # 5 + 'Prime 2', # 6 + 'Prime exponent 1', # 7 + 'Prime exponent 2', # 8 + 'Coefficient', # 9 +] + +def key_consitency_check(k) + return true +end + +def process_file(f, skip_key=1, skip_vec=1) + a = get_next_block(f) + key_no = 0 + ok_counter = 0 + fail_counter = 0 + begin + if !a || ! a['tag'] == 'Modulus' + printf("ERROR: a = %s %d\n", a.inspect, __LINE__) + return + end + k_seq = Array.new + k_seq[0] = a + (1..($key_sequence.length-1)).each do |i| + a = get_next_block(f) + if ! a || a['tag'] != $key_sequence[i] + printf("ERROR: (expecting: %s) a = %s %d\n", $key_sequence[i], a.inspect, __LINE__) + end + k_seq[i] = a + end + key = convert_key(k_seq) + printf("ERROR: %d\n", __LINE__) if ! key + key_no += 1 + vec_no = 0 + printf("\n run %3d: ", key_no) + skip_key_flag = (key_no < skip_key) + load_key(key) if ! skip_key_flag + test_seq = Array.new + a = get_next_block(f) + printf("ERROR: %d\n", __LINE__) if ! a + begin + vec_no += 1 + b = get_next_block(f) + c = get_next_block(f) + tv = Hash.new + tv['msg'] = a['data'] + tv['seed'] = b['data'] + tv['enc'] = c['data'] + skip_vec_flag = (skip_key_flag || (key_no == skip_key && vec_no < skip_vec)) + if skip_vec_flag + printf('o') + else + v = check_tv(tv) + if(v == true) + printf('*') + $logfile.printf("[[Test %2d.%02d = OK]]\n", key_no, vec_no) + ok_counter += 1 + else + printf('%c', v ? '*' : '!') + $logfile.printf("[[Test %2d.%02d = FAIL]]\n", key_no, vec_no) + fail_counter += 1 + end + end + a = get_next_block(f) + end while a && a['tag'] == 'Message' + end while a && a['tag'] = 'Modulus' +# printf("\nResult: %d OK / %d FAIL ==> %s \nFinished\n", ok_counter, fail_counter, fail_counter==0 ? ':-)' : ':-(') + return ok_counter,fail_counter +end + +def convert_key(k_seq) + l = ['n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv'] + r = Hash.new + return nil if k_seq[0]['data'] != k_seq[2]['data'] + return nil if k_seq[1]['data'] != k_seq[3]['data'] + 8.times do |i| + r[l[i]] = k_seq[2 + i]['data'] + end + return r +end + +def wait_for_dot + begin + s = $sp.gets() + end while !s || !s.include?('.') +end + +def load_bigint(d) + $sp.printf("%d\r", d.length) + while l = read_line_from_device() + break if /data:/.match(l) + end + printf "ERROR: got no answer from system!" if !l + i = 0 + d.each do |e| + $sp.printf("%02x", e) + i += 1 + if i % 60 == 0 +# we should now wait for incomming dot + wait_for_dot() + print('.') + end + end +end + +def hexdump(a) + i = 0 + a.each do |e| + printf("\n\t") if i % 16 == 0 + printf('%02x ', e) + i += 1 + end + puts('') if i % 16 != 1 +end + +def str_hexdump(a) + i = 0 + s = '' + a.each do |e| + s += "\n\t" if i % 16 == 0 + s += sprintf('%02x ', e) + i += 1 + end + s += "\n" if i % 16 != 1 + return s +end + +def load_key(k) + $sp.print("load-key\r") + sleep 0.1 + v = ['n', 'e', 'p', 'q', 'dP', 'dQ', 'qInv'] + v.each do |e| + load_bigint(k[e]) + $logfile.printf("DBG: loaded %s\n", e) if $debug + end + while l = read_line_from_device() + break if />/.match(l) + end +end + +def strip_leading_zeros(a) + loop do + return [] if a.length == 0 + return a if a[0] != 0 + a.delete_at(0) + end +end + +def check_tv(tv) + sleep 0.1 + $sp.print("seed-test\r") + sleep 0.1 + load_bigint(tv['msg']) + $logfile.printf("DBG: loaded %s\n", 'msg') if $debug + sleep 0.1 + tv['seed'].each { |e| $sp.printf(" %02x", e) } + while l = read_line_from_device() + break if /ciphertext:/.match(l) + end + test_enc = '' + loop do + l = read_line_from_device() + t = l.split + v = false + t.each { |e| v = true if e.length != 2 } + x = t.collect { |e| e.to_i(16) } + break if v + test_enc += l if l + end + test_enc_a = Array.new + test_enc = test_enc.split(/[\W\r\n]+/) + test_enc.each do |e| + v = e.sub(/[^0-9A-Fa-f]/, '') + test_enc_a << v if v.length == 2 + end + test_enc_a.collect!{ |e| e.to_i(16) } + strip_leading_zeros(test_enc_a) + strip_leading_zeros(tv['enc']) + enc_ok = (test_enc_a == tv['enc']) + if !enc_ok + $logfile.printf("DBG: ref = %s test = %s\n", str_hexdump(tv['enc']) , str_hexdump(test_enc_a)) + end + m = nil + loop do + l = read_line_from_device() + m = /(>>OK<<|ERROR)/.match(l) + break if m + end + return true if enc_ok && (m[1] == '>>OK<<') + return false +end + +######################################## +# MAIN +######################################## + + +opts = Getopt::Std.getopts('dc:f:il:s:n:') + +conf = Hash.new +conf = readconfigfile("/etc/testport.conf", conf) +conf = readconfigfile("~/.testport.conf", conf) +conf = readconfigfile("testport.conf", conf) +conf = readconfigfile(opts["c"], conf) if opts["c"] + +#puts conf.inspect + +puts("serial port interface version: " + SerialPort::VERSION); +$linewidth = 64 +params = { "baud" => conf["PORT"]["baud"].to_i, + "data_bits" => conf["PORT"]["databits"].to_i, + "stop_bits" => conf["PORT"]["stopbits"].to_i, + "parity" => SerialPort::NONE } +params["paraty"] = SerialPort::ODD if conf["PORT"]["paraty"].downcase == "odd" +params["paraty"] = SerialPort::EVEN if conf["PORT"]["paraty"].downcase == "even" +params["paraty"] = SerialPort::MARK if conf["PORT"]["paraty"].downcase == "mark" +params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space" + +puts("\nPort: "+conf["PORT"]["port"]+"@" + + params["baud"].to_s + + " " + + params["data_bits"].to_s + + conf["PORT"]["paraty"][0,1].upcase + + params["stop_bits"].to_s + + "\n") + +$sp = SerialPort.new(conf["PORT"]["port"], params) + +$sp.read_timeout=1000; # 5 minutes +$sp.flow_control = SerialPort::SOFT + +$debug = true if opts['d'] + +if opts['l'] && ! opts['n'] + $logfile = File.open(opts['l'], 'w') +end + +if opts['n'] + logfilename = conf['PORT']['testlogbase']+'rsa_pkcs1v15_' + opts['n'] + '.txt' + if File.exists?(logfilename) + i=1 + begin + logfilename = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'rsa_pkcs1v15_'+opts['n']+'_',i,'.txt') + i+=1 + end while(File.exists?(logfilename)) + while(i>2) do + n1 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'rsa_pkcs1v15_'+opts['n']+'_',i-2,'.txt') + n2 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'rsa_pkcs1v15_'+opts['n']+'_',i-1,'.txt') + File.rename(n1, n2) + printf("%s -> %s\n", n1, n2) + i-=1 + end + n1 = sprintf('%s%s', conf['PORT']['testlogbase'],'rsa_pkcs1v15_'+opts['n']+'.txt') + n2 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'rsa_pkcs1v15_'+opts['n']+'_',1,'.txt') + File.rename(n1, n2) + printf("%s -> %s\n", n1, n2) + logfilename = conf['PORT']['testlogbase']+'rsa_pkcs1v15_'+opts['n']+'.txt' + end + printf("logging to %s", logfilename) + $logfile = File.open(logfilename, 'w') +end + +$logfile = STDOUT if ! $logfile +reset_system() + +if opts['s'] && ( m = opts['s'].match(/([\d]+)\.([\d]+)/) ) + sk = m[1].to_i + sv = m[2].to_i +else + sk = 1 + sv = 1 +end + +f = File.open(opts['f'], "r") +exit if !f +ok,fail = process_file(f,sk,sv) +printf("\nOK: %d FAIL: %d :-%s\n",ok,fail, fail==0 ? ')':'(') + + diff --git a/khazad/khazad.c b/khazad/khazad.c index 045de13..9da7dea 100644 --- a/khazad/khazad.c +++ b/khazad/khazad.c @@ -92,7 +92,7 @@ uint8_t khazad_sbox(uint8_t a){ return b|c; } -static void gamma(uint8_t* a){ +static void gamma_1(uint8_t* a){ uint8_t i; for(i=0; i<8; ++i){ *a = khazad_sbox(*a); @@ -147,7 +147,7 @@ static void theta(uint8_t* a){ /******************************************************************************/ static void khazad_round(uint8_t* a, const uint8_t* k){ - gamma(a); + gamma_1(a); theta(a); memxor(a, k, 8); } @@ -188,7 +188,7 @@ void khazad_enc(void* buffer, const khazad_ctx_t* ctx){ for(r=1; r<8; ++r){ khazad_round(buffer, ctx->k[r]); } - gamma(buffer); + gamma_1(buffer); memxor(buffer, ctx->k[8], 8); } @@ -197,11 +197,11 @@ void khazad_enc(void* buffer, const khazad_ctx_t* ctx){ void khazad_dec(void* buffer, const khazad_ctx_t* ctx){ uint8_t r=7; memxor(buffer, ctx->k[8], 8); - gamma(buffer); + gamma_1(buffer); do{ memxor(buffer, ctx->k[r--], 8); theta(buffer); - gamma(buffer); + gamma_1(buffer); }while(r); memxor(buffer, ctx->k[0], 8); } diff --git a/md5/md5.c b/md5/md5.c index 003699e..3feddd6 100644 --- a/md5/md5.c +++ b/md5/md5.c @@ -139,32 +139,35 @@ void md5_nextBlock(md5_ctx_t *state, const void* block){ void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length_b){ uint16_t l; - uint8_t b[64]; + union { + uint8_t v8[64]; + uint64_t v64[ 8]; + } buffer; while (length_b >= 512){ md5_nextBlock(state, block); length_b -= 512; block = ((uint8_t*)block) + 512/8; } - memset(b, 0, 64); - memcpy(b, block, length_b/8); + memset(buffer.v8, 0, 64); + memcpy(buffer.v8, block, length_b/8); /* insert padding one */ l=length_b/8; if(length_b%8){ uint8_t t; t = ((uint8_t*)block)[l]; t |= (0x80>>(length_b%8)); - b[l]=t; + buffer.v8[l]=t; }else{ - b[l]=0x80; + buffer.v8[l]=0x80; } /* insert length value */ if(l+sizeof(uint64_t) >= 512/8){ - md5_nextBlock(state, b); + md5_nextBlock(state, buffer.v8); state->counter--; - memset(b, 0, 64-8); + memset(buffer.v8, 0, 64-8); } - *((uint64_t*)&b[64-sizeof(uint64_t)]) = (state->counter * 512) + length_b; - md5_nextBlock(state, b); + buffer.v64[7] = (state->counter * 512) + length_b; + md5_nextBlock(state, buffer.v8); } void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state){ diff --git a/mkfiles/rsa_oaep.mk b/mkfiles/rsa_oaep.mk deleted file mode 100644 index 59c1a39..0000000 --- a/mkfiles/rsa_oaep.mk +++ /dev/null @@ -1,14 +0,0 @@ -# Makefile for RSA -ALGO_NAME := RSA_OAEP - -# comment out the following line for removement of RSA from the build process -PK_CIPHERS += $(ALGO_NAME) - -$(ALGO_NAME)_DIR := rsa/ -$(ALGO_NAME)_INCDIR := memxor/ bigint/ noekeon/ hfal/ sha1/ mgf1/ -$(ALGO_NAME)_OBJ := bigint.o bigint_io.o rsa_basic.o rsa_oaep.o mgf1.o hfal-basic.o hfal_sha1.o sha1.o -$(ALGO_NAME)_TESTBIN := main-rsa_oaep-test.o $(CLI_STD) random_dummy.o \ - noekeon.o noekeon_prng.o memxor.o - -$(ALGO_NAME)_PERFORMANCE_TEST := performance - diff --git a/mkfiles/rsa_pkcs15.mk b/mkfiles/rsa_pkcs15.mk deleted file mode 100644 index 89c9fb1..0000000 --- a/mkfiles/rsa_pkcs15.mk +++ /dev/null @@ -1,14 +0,0 @@ -# Makefile for RSA -ALGO_NAME := RSA_PKCS15 - -# comment out the following line for removement of RSA from the build process -SIGNATURE += $(ALGO_NAME) - -$(ALGO_NAME)_DIR := rsa/ -$(ALGO_NAME)_INCDIR := memxor/ bigint/ noekeon/ -$(ALGO_NAME)_OBJ := bigint.o bigint_io.o rsa_basic.o rsa_pkcs15.o -$(ALGO_NAME)_TESTBIN := main-rsa_pkcs15-test.o $(CLI_STD) random_dummy.o \ - noekeon.o noekeon_prng.o memxor.o - -$(ALGO_NAME)_PERFORMANCE_TEST := performance - diff --git a/mkfiles/rsaes_oaep.mk b/mkfiles/rsaes_oaep.mk new file mode 100644 index 0000000..0b0b682 --- /dev/null +++ b/mkfiles/rsaes_oaep.mk @@ -0,0 +1,14 @@ +# Makefile for RSA +ALGO_NAME := RSAES_OAEP + +# comment out the following line for removement of RSA from the build process +PK_CIPHERS += $(ALGO_NAME) + +$(ALGO_NAME)_DIR := rsa/ +$(ALGO_NAME)_INCDIR := memxor/ bigint/ noekeon/ hfal/ sha1/ mgf1/ +$(ALGO_NAME)_OBJ := bigint.o bigint_io.o rsa_basic.o rsaes_oaep.o mgf1.o hfal-basic.o hfal_sha1.o sha1.o +$(ALGO_NAME)_TESTBIN := main-rsaes_oaep-test.o $(CLI_STD) random_dummy.o \ + noekeon.o noekeon_prng.o memxor.o + +$(ALGO_NAME)_PERFORMANCE_TEST := performance + diff --git a/mkfiles/rsaes_pkcs1v15.mk b/mkfiles/rsaes_pkcs1v15.mk new file mode 100644 index 0000000..8d15289 --- /dev/null +++ b/mkfiles/rsaes_pkcs1v15.mk @@ -0,0 +1,14 @@ +# Makefile for RSA +ALGO_NAME := RSAES_PKCS1V15 + +# comment out the following line for removement of RSA from the build process +SIGNATURE += $(ALGO_NAME) + +$(ALGO_NAME)_DIR := rsa/ +$(ALGO_NAME)_INCDIR := memxor/ bigint/ noekeon/ +$(ALGO_NAME)_OBJ := bigint.o bigint_io.o rsa_basic.o rsaes_pkcs1v15.o +$(ALGO_NAME)_TESTBIN := main-rsaes_pkcs1v15-test.o $(CLI_STD) random_dummy.o \ + noekeon.o noekeon_prng.o memxor.o + +$(ALGO_NAME)_PERFORMANCE_TEST := performance + diff --git a/noekeon/noekeon.c b/noekeon/noekeon.c index 8c4d6be..0fbdcf9 100644 --- a/noekeon/noekeon.c +++ b/noekeon/noekeon.c @@ -39,7 +39,7 @@ #define RC_POS 0 static -void gamma(uint32_t* a){ +void gamma_1(uint32_t* a){ uint32_t tmp; a[1] ^= ~((a[3]) | (a[2])); @@ -94,7 +94,7 @@ void noekeon_round(uint32_t* key, uint32_t* state, uint8_t const1, uint8_t const theta(key, state); ((uint8_t*)state)[RC_POS] ^= const2; pi1(state); - gamma(state); + gamma_1(state); pi2(state); } diff --git a/rsa/rsa_basic.c b/rsa/rsa_basic.c index b0ef12b..98cdfb2 100644 --- a/rsa/rsa_basic.c +++ b/rsa/rsa_basic.c @@ -52,50 +52,111 @@ m = m2 + q * h uint8_t rsa_dec_crt_mono(bigint_t* data, rsa_privatekey_t* key){ bigint_t m1, m2; - m1.wordv = malloc((key->modulus->length_B + 1) * sizeof(bigint_word_t)); - m2.wordv = malloc(key->components[1]->length_B * sizeof(bigint_word_t)); + m1.wordv = malloc((key->components[0]->length_B + 1) * sizeof(bigint_word_t)); + m2.wordv = malloc((key->components[1]->length_B + 1) * sizeof(bigint_word_t)); if(!m1.wordv || !m2.wordv){ #if DEBUG - cli_putstr_P(PSTR("\r\nERROR: OOM! (" __FILE__ ")")); + cli_putstr_P(PSTR("\r\nERROR: OOM!")); #endif free(m1.wordv); free(m2.wordv); return 1; } #if DEBUG - cli_putstr_P(PSTR("\r\nexp_mod a + b ")); + cli_putstr_P(PSTR("\r\nDBG: expmod m1 ...")); + cli_putstr_P(PSTR("\r\nexpmod(")); + bigint_print_hex(data); + cli_putc(','); + bigint_print_hex(key->components[2]); + cli_putc(','); + bigint_print_hex(key->components[0]); + cli_putstr_P(PSTR(") = ")); #endif bigint_expmod_u(&m1, data, key->components[2], key->components[0]); +#if DEBUG + bigint_print_hex(&m1); + cli_putstr_P(PSTR("expmod m2 ...")); + cli_putstr_P(PSTR("\r\nexpmod(")); + bigint_print_hex(data); + cli_putc(','); + bigint_print_hex(key->components[3]); + cli_putc(','); + bigint_print_hex(key->components[1]); + cli_putstr_P(PSTR(") = ")); +#endif bigint_expmod_u(&m2, data, key->components[3], key->components[1]); #if DEBUG - cli_putstr_P(PSTR("[done] ")); + bigint_print_hex(&m2); + cli_putstr_P(PSTR("\r\nDBG: sub ...")); + cli_putstr_P(PSTR("\r\nsub(")); + bigint_print_hex(&m1); + cli_putc(','); + bigint_print_hex(&m2); + cli_putstr_P(PSTR(") = ")); #endif bigint_sub_s(&m1, &m1, &m2); #if DEBUG - cli_putstr_P(PSTR("[done2] ")); + bigint_print_hex(&m1); #endif while(BIGINT_NEG_MASK & m1.info){ #if DEBUG - cli_putc(','); + cli_putstr_P(PSTR("\r\nDBG: adding ")); + bigint_print_hex(key->components[0]); + cli_putstr_P(PSTR("\r\nDBG: to ")); + bigint_print_hex(&m1); #endif bigint_add_s(&m1, &m1, key->components[0]); } #if DEBUG - cli_putstr_P(PSTR("\r\nreduce_mul ")); + cli_putstr_P(PSTR("\r\nDBG: reduce-mul ...")); + cli_putstr_P(PSTR("\r\nreduce(")); + bigint_print_hex(&m1); + cli_putc(','); + bigint_print_hex(key->components[0]); + cli_putstr_P(PSTR(") = ")); #endif bigint_reduce(&m1, key->components[0]); - bigint_mul_u(&m1, &m1, key->components[4]); #if DEBUG - cli_putstr_P(PSTR("[done]")); + bigint_print_hex(&m1); + cli_putstr_P(PSTR("\r\nmul(")); + bigint_print_hex(&m1); + cli_putc(','); + bigint_print_hex(key->components[4]); + cli_putstr_P(PSTR(") = ")); #endif - bigint_reduce(&m1, key->components[0]); - bigint_mul_u(&m1, &m1, key->components[1]); + bigint_mul_u(data, &m1, key->components[4]); #if DEBUG - cli_putstr_P(PSTR(" [done]")); + bigint_print_hex(data); + cli_putstr_P(PSTR("\r\nreduce(")); + bigint_print_hex(data); + cli_putc(','); + bigint_print_hex(key->components[0]); + cli_putstr_P(PSTR(") = ")); +#endif + bigint_reduce(data, key->components[0]); +#if DEBUG + bigint_print_hex(data); + cli_putstr_P(PSTR("\r\nmul(")); + bigint_print_hex(data); + cli_putc(','); + bigint_print_hex(key->components[1]); + cli_putstr_P(PSTR(") = ")); +#endif + bigint_mul_u(data, data, key->components[1]); +#if DEBUG + bigint_print_hex(data); + cli_putstr_P(PSTR("\r\nadd(")); + bigint_print_hex(data); + cli_putc(','); + bigint_print_hex(&m2); + cli_putstr_P(PSTR(") = ")); +#endif + bigint_add_u(data, data, &m2); +#if DEBUG + bigint_print_hex(data); #endif - bigint_add_u(data, &m1, &m2); - free(m1.wordv); free(m2.wordv); + free(m1.wordv); return 0; } @@ -118,8 +179,18 @@ uint8_t rsa_dec(bigint_t* data, rsa_privatekey_t* key){ } void rsa_os2ip(bigint_t* dest, const void* data, uint32_t length_B){ +#if BIGINT_WORD_SIZE == 8 + if(data){ + memcpy(dest->wordv, data, length_B); + } + dest->length_B = length_B; +#else uint8_t off; - off = length_B % sizeof(bigint_word_t); + off = (sizeof(bigint_word_t) - length_B % sizeof(bigint_word_t)) % sizeof(bigint_word_t); +#if DEBUG + cli_putstr_P(PSTR("\r\nDBG: off = 0x")); + cli_hexdump_byte(off); +#endif if(!data){ if(off){ dest->wordv = realloc(dest->wordv, length_B + sizeof(bigint_word_t) - off); @@ -127,19 +198,37 @@ void rsa_os2ip(bigint_t* dest, const void* data, uint32_t length_B){ memset(dest->wordv, 0, off); } }else{ + memcpy((uint8_t*)dest->wordv + off, data, length_B); if(off){ - memcpy((uint8_t*)dest->wordv + off, data, length_B); - memset(dest, 0, off); - }else{ - memcpy(dest->wordv, data, length_B); + memset(dest->wordv, 0, off); } } - dest->length_B = (length_B + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + dest->length_B = (length_B + off) / sizeof(bigint_word_t); +#if DEBUG + cli_putstr_P(PSTR("\r\nDBG: dest->length_B = 0x")); + cli_hexdump_rev(&(dest->length_B), 2); +#endif +#endif + dest->info = 0; bigint_changeendianess(dest); bigint_adjust(dest); } void rsa_i2osp(void* dest, bigint_t* src, uint16_t* out_length_B){ +#if BIGINT_WORD_SIZE == 8 + if(dest){ + uint8_t *e = src->wordv + src->length_B; + uint16_t i; + for(i=src->length_B; i>0; --i){ + *((uint8_t*)dest) = *--e; + dest = (uint8_t*)dest + 1; + } + }else{ + bigint_changeendianess(src); + } + + *out_length_B = src->length_B; +#else *out_length_B = bigint_get_first_set_bit(src) / 8 + 1; if(dest){ uint16_t i; @@ -157,5 +246,6 @@ void rsa_i2osp(void* dest, bigint_t* src, uint16_t* out_length_B){ memmove(src->wordv, (uint8_t*)src->wordv+off, *out_length_B); } } +#endif } diff --git a/rsa/rsa_oaep.c b/rsa/rsa_oaep.c deleted file mode 100644 index 96d1a92..0000000 --- a/rsa/rsa_oaep.c +++ /dev/null @@ -1,247 +0,0 @@ - -/* rsa_oaep.c */ -/* - This file is part of the ARM-Crypto-Lib. - Copyright (C) 2006-2012 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include -#include -#include -#include "memxor.h" -#include "mgf1.h" -#include "bigint.h" -#include "rsa_basic.h" -#include "rsa_oaep.h" - -#include "random_dummy.h" - -#include "hfal/hfal_sha1.h" - -#define DEBUG 0 - -#if DEBUG -#include "cli.h" -#endif - -mgf1_parameter_t mgf1_default_parameter = { - &sha1_desc -}; - -rsa_oaep_parameter_t rsa_oaep_default_parameter = { - mgf1, - &sha1_desc, - &mgf1_default_parameter -}; - -rsa_label_t rsa_oaep_default_label = { - 0, NULL -}; - -uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length, - const void* src, uint16_t length_B, - rsa_publickey_t* key, const rsa_oaep_parameter_t *p, - const rsa_label_t* label, const void* seed){ - - if(!p){ - p = &rsa_oaep_default_parameter; - } - if(!label){ - label = &rsa_oaep_default_label; - } - uint16_t hv_len = (hfal_hash_getHashsize(p->hf)+7)/8; - if(length_B > bigint_length_B(key->modulus) - 2*hv_len - 2){ - /* message too long */ - return 1; - } - uint16_t buffer_len = bigint_length_B(key->modulus); -#if DEBUG - cli_putstr("\r\n buffer_len = "); - cli_hexdump_rev(&buffer_len, 2); - cli_putstr("\r\n modulus_len = "); - cli_hexdump_rev(&key->modulus->length_B, 2); -#endif - uint8_t* buffer = (uint8_t*)dest; - uint8_t off; - /* the following needs some explanation: - * off is the offset which is used for compensating the effect of - * changeendian() when it operates on multi-byte words. - * */ - off = (sizeof(bigint_word_t) - (bigint_get_first_set_bit(key->modulus)/8+1) % sizeof(bigint_word_t)) - % (sizeof(bigint_word_t)); - buffer += off; - buffer_len -= off; - uint8_t* seed_buffer = buffer + 1; - uint16_t db_len = buffer_len - hv_len - 1; - uint8_t* db = seed_buffer + hv_len; - uint16_t maskbuffer_len = db_len>hv_len?db_len:hv_len; - uint8_t maskbuffer[maskbuffer_len]; - bigint_t x; - - memset(dest, 0, seed_buffer - buffer + off); - memset(db + hv_len, 0, db_len - hv_len - length_B -1); - hfal_hash_mem(p->hf, db, label->label, label->length_b); - db[db_len - length_B - 1] = 0x01; - memcpy(db+db_len - length_B, src, length_B); - if(seed){ - memcpy(seed_buffer, seed, hv_len); - }else{ - /* generate random seed */ - if(!prng_get_byte){ - return 2; /* ERROR: no random generator specified */ - } - uint16_t i; - for(i=0; imodulus), 4, 16); -#endif - p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter); - memxor(db, maskbuffer, db_len); - p->mgf(maskbuffer, db, db_len, hv_len, p->mgf_parameter); - memxor(seed_buffer, maskbuffer, hv_len); -#if DEBUG - cli_putstr("\r\n msg (raw, post-feistel):\r\n"); - cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16); -#endif - x.info = 0; - x.length_B = key->modulus->length_B; - x.wordv = dest; - bigint_adjust(&x); - rsa_os2ip(&x, NULL, bigint_length_B(key->modulus)); -#if DEBUG - cli_putstr("\r\ninput-msg (pre enc):\r\n"); - cli_hexdump_rev(&src, 2); - cli_hexdump_block(src, length_B, 4, 16); -#endif - rsa_enc(&x, key); -#if DEBUG - cli_putstr("\r\ninput-msg (post enc):\r\n"); - cli_hexdump_rev(&src, 2); - cli_hexdump_block(src, length_B, 4, 16); -#endif - rsa_i2osp(NULL, &x, out_length); - return 0; -} - -uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length, - const void* src, uint16_t length_B, - rsa_privatekey_t* key, const rsa_oaep_parameter_t *p, - const rsa_label_t* label, void* seed){ - -// cli_putstr("\r\n -->rsa_decrypt_oaep()"); uart_flush(0); - if(!label){ - label = &rsa_oaep_default_label; - } - if(!p){ - p = &rsa_oaep_default_parameter; - } - uint16_t x_len, data_len; - bigint_t x; - uint16_t hv_len = hfal_hash_getHashsize(p->hf)/8; - uint8_t label_hv[hv_len]; - uint16_t msg_len = bigint_get_first_set_bit(key->modulus) / 8 + 1; - uint16_t db_len = msg_len - hv_len - 1; - uint8_t maskbuffer[db_len>hv_len?db_len:hv_len]; - - uint8_t *seed_buffer = dest; - uint8_t *db_buffer = seed_buffer + hv_len; - - x_len = bigint_get_first_set_bit(key->modulus)/8; - memset(dest, 0, bigint_length_B(key->modulus) - length_B); - memcpy((uint8_t*)dest + bigint_length_B(key->modulus) - length_B, src, length_B); - -// cli_putc('a'); uart_flush(0); - - x.wordv = dest; - x.length_B = key->modulus->length_B; - x.info = 0; - bigint_adjust(&x); - - -// cli_putc('b'); uart_flush(0); - rsa_os2ip(&x, NULL, bigint_length_B(key->modulus)); -#if DEBUG - cli_putstr_P(PSTR("\r\n rsa decrypting ...")); -#endif - rsa_dec(&x, key); -#if DEBUG - cli_putstr_P(PSTR(" [done]")); -#endif - rsa_i2osp(NULL, &x, &data_len); - -// cli_putstr("\r\n msg (raw, pre-move):\r\n"); -// cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16); - - if(data_len > x_len){ - return 7; - } -/* - cli_putstr("\r\n moving some bytes; x_len = "); - cli_hexdump_rev(&x_len, 2); - cli_putstr(" data_len = "); - cli_hexdump_rev(&data_len, 2); - uart_flush(0); -*/ - if(x_len != data_len){ - memmove((uint8_t*)dest + x_len - data_len, dest, data_len); -// cli_putstr(" (oh, not dead yet?!)"); -// uart_flush(0); - memset(dest, 0, x_len - data_len); - } - - hfal_hash_mem(p->hf, label_hv, label->label, label->length_b); -/* - cli_putstr("\r\n msg (raw, pre-feistel):\r\n"); - cli_hexdump_block(seed_buffer, bigint_length_B(key->modulus), 4, 16); - uart_flush(0); -*/ - p->mgf(maskbuffer, db_buffer, db_len, hv_len, p->mgf_parameter); - memxor(seed_buffer, maskbuffer, hv_len); - p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter); - memxor(db_buffer, maskbuffer, db_len); - - if(memcmp(label_hv, db_buffer, hv_len)){ -// cli_putstr("\r\nDBG: DB:\r\n"); -// cli_hexdump_block(db_buffer, db_len, 4, 16); - return 2; - } - - uint16_t ps_len=0; - while(db_buffer[hv_len + ps_len++] == 0) - ; - - --ps_len; - if(db_buffer[hv_len + ps_len] != 1){ - return 3; - } - - if(seed){ - memcpy(seed, seed_buffer, hv_len); - } - - msg_len = db_len - hv_len - 1 - ps_len; - memmove(dest, db_buffer + hv_len + ps_len + 1, msg_len); - - *out_length = msg_len; - - return 0; -} - - diff --git a/rsa/rsa_oaep.h b/rsa/rsa_oaep.h deleted file mode 100644 index 8084653..0000000 --- a/rsa/rsa_oaep.h +++ /dev/null @@ -1,54 +0,0 @@ -/* rsa_oaep.h */ -/* - This file is part of the AVR-Crypto-Lib. - Copyright (C) 2012 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef RSA_OAEP_H_ -#define RSA_OAEP_H_ - -#include -#include "mgf1.h" - - -void mgf1(void* dest, const void* seed, uint16_t seed_len_B, uint16_t out_length_B, const mgf1_parameter_t* p); - - -typedef struct { - void (*mgf)(void* dst, const void* seed, uint16_t slen_B, uint16_t dstlen_B, const mgf1_parameter_t* p); - const hfdesc_t* hf; - mgf1_parameter_t* mgf_parameter; -} rsa_oaep_parameter_t; - -typedef struct { - uint16_t length_b; - const void* label; -} rsa_label_t; - -extern rsa_oaep_parameter_t rsa_oaep_default_parameter; -extern rsa_label_t rsa_oaep_default_label; - -uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length, - const void* src, uint16_t length_B, - rsa_publickey_t* key, const rsa_oaep_parameter_t *p, - const rsa_label_t* label, const void* seed); - -uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length, - const void* src, uint16_t length_B, - rsa_privatekey_t* key, const rsa_oaep_parameter_t *p, - const rsa_label_t* label, void* seed); - -#endif /* RSA_OAEP_H_ */ diff --git a/rsa/rsa_pkcs15.c b/rsa/rsa_pkcs15.c deleted file mode 100644 index b1ec7ca..0000000 --- a/rsa/rsa_pkcs15.c +++ /dev/null @@ -1,134 +0,0 @@ -/* rsa_pkcs15.c */ -/* - This file is part of the ARM-Crypto-Lib. - Copyright (C) 2006-2011 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include -#include -#include -#include "bigint.h" -#include "rsa_basic.h" - -#define DEBUG 0 - -#if DEBUG -#include "bigint_io.h" -#include "cli.h" -#endif - -#include "random_dummy.h" - -uint16_t rsa_pkcs15_compute_padlength_B(bigint_t* modulus, uint16_t msg_length_B){ - return bigint_get_first_set_bit(modulus) / 8 + 1 - msg_length_B - 3; -} - -uint8_t rsa_encrypt_pkcs15(void* dest, uint16_t* out_length, const void* src, - uint16_t length_B, rsa_publickey_t* key, const void* pad){ - int16_t pad_length; - bigint_t x; - pad_length = rsa_pkcs15_compute_padlength_B(key->modulus, length_B); - if(pad_length<8){ -#if DEBUG - cli_putstr_P(PSTR("\r\nERROR: pad_length<8; pad_length: ")); - cli_hexdump_rev(&pad_length, 2); -#endif - return 2; /* message to long */ - } - if(!pad){ -#if DEBUG - cli_putstr_P(PSTR("\r\nauto-generating pad ...")); -#endif - uint16_t i; - uint8_t c; - for(i=0; i=m_length){ - return 1; - } - ++idx; - while(((uint8_t*)x.wordv)[idx+pad_length]!=0 && (idx+pad_length)=m_length){ - return 2; - } - *out_length = m_length - idx - pad_length - 1; - if(pad){ -#if DEBUG - cli_putstr_P(PSTR("\r\npadding block:")); - cli_hexdump_block(((uint8_t*)x.wordv)+idx, pad_length, 4, 16); - cli_putstr_P(PSTR("\r\npad @ 0x")); - cli_hexdump_rev(&pad, 2); - cli_putstr_P(PSTR("\r\ndst @ 0x")); - cli_hexdump_rev(&dest, 2); -#endif - memcpy(pad, ((uint8_t*)x.wordv)+idx, pad_length); - } - memmove(dest, ((uint8_t*)x.wordv) + idx + pad_length + 1, m_length - idx - pad_length - 1); - - return 0; -} - diff --git a/rsa/rsa_pkcs15.h b/rsa/rsa_pkcs15.h deleted file mode 100644 index ff1b26d..0000000 --- a/rsa/rsa_pkcs15.h +++ /dev/null @@ -1,35 +0,0 @@ -/* rsa_pkcs15.h */ -/* - This file is part of the AVR-Crypto-Lib. - Copyright (C) 2011 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef RSA_PKCS15_H_ -#define RSA_PKCS15_H_ - -#include -#include "bigint.h" - -uint16_t rsa_pkcs15_compute_padlength_B(bigint_t* modulus, uint16_t msg_length_B); - - -uint8_t rsa_encrypt_pkcs15(void* dest, uint16_t* out_length, const void* src, - uint16_t length_B, rsa_publickey_t* key, const void* pad); - -uint8_t rsa_decrypt_pkcs15(void* dest, uint16_t* out_length, const void* src, - uint16_t length_B, rsa_privatekey_t* key, void* pad); - -#endif /* RSA_PKCS15_H_ */ diff --git a/rsa/rsaes_oaep.c b/rsa/rsaes_oaep.c new file mode 100644 index 0000000..0fc0c04 --- /dev/null +++ b/rsa/rsaes_oaep.c @@ -0,0 +1,247 @@ + +/* rsa_oaep.c */ +/* + This file is part of the ARM-Crypto-Lib. + Copyright (C) 2006-2012 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include "memxor.h" +#include "mgf1.h" +#include "bigint.h" +#include "rsa_basic.h" +#include "rsaes_oaep.h" + +#include "random_dummy.h" + +#include "hfal/hfal_sha1.h" + +#define DEBUG 0 + +#if DEBUG +#include "cli.h" +#endif + +mgf1_parameter_t mgf1_default_parameter = { + &sha1_desc +}; + +rsa_oaep_parameter_t rsa_oaep_default_parameter = { + mgf1, + &sha1_desc, + &mgf1_default_parameter +}; + +rsa_label_t rsa_oaep_default_label = { + 0, NULL +}; + +uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length, + const void* src, uint16_t length_B, + rsa_publickey_t* key, const rsa_oaep_parameter_t *p, + const rsa_label_t* label, const void* seed){ + + if(!p){ + p = &rsa_oaep_default_parameter; + } + if(!label){ + label = &rsa_oaep_default_label; + } + uint16_t hv_len = (hfal_hash_getHashsize(p->hf)+7)/8; + if(length_B > bigint_length_B(key->modulus) - 2*hv_len - 2){ + /* message too long */ + return 1; + } + uint16_t buffer_len = bigint_length_B(key->modulus); +#if DEBUG + cli_putstr("\r\n buffer_len = "); + cli_hexdump_rev(&buffer_len, 2); + cli_putstr("\r\n modulus_len = "); + cli_hexdump_rev(&key->modulus->length_B, 2); +#endif + uint8_t* buffer = (uint8_t*)dest; + uint8_t off; + /* the following needs some explanation: + * off is the offset which is used for compensating the effect of + * changeendian() when it operates on multi-byte words. + * */ + off = (sizeof(bigint_word_t) - (bigint_get_first_set_bit(key->modulus)/8+1) % sizeof(bigint_word_t)) + % (sizeof(bigint_word_t)); + buffer += off; + buffer_len -= off; + uint8_t* seed_buffer = buffer + 1; + uint16_t db_len = buffer_len - hv_len - 1; + uint8_t* db = seed_buffer + hv_len; + uint16_t maskbuffer_len = db_len>hv_len?db_len:hv_len; + uint8_t maskbuffer[maskbuffer_len]; + bigint_t x; + + memset(dest, 0, seed_buffer - buffer + off); + memset(db + hv_len, 0, db_len - hv_len - length_B -1); + hfal_hash_mem(p->hf, db, label->label, label->length_b); + db[db_len - length_B - 1] = 0x01; + memcpy(db+db_len - length_B, src, length_B); + if(seed){ + memcpy(seed_buffer, seed, hv_len); + }else{ + /* generate random seed */ + if(!prng_get_byte){ + return 2; /* ERROR: no random generator specified */ + } + uint16_t i; + for(i=0; imodulus), 4, 16); +#endif + p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter); + memxor(db, maskbuffer, db_len); + p->mgf(maskbuffer, db, db_len, hv_len, p->mgf_parameter); + memxor(seed_buffer, maskbuffer, hv_len); +#if DEBUG + cli_putstr("\r\n msg (raw, post-feistel):\r\n"); + cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16); +#endif + x.info = 0; + x.length_B = key->modulus->length_B; + x.wordv = dest; + bigint_adjust(&x); + rsa_os2ip(&x, NULL, bigint_length_B(key->modulus)); +#if DEBUG + cli_putstr("\r\ninput-msg (pre enc):\r\n"); + cli_hexdump_rev(&src, 2); + cli_hexdump_block(src, length_B, 4, 16); +#endif + rsa_enc(&x, key); +#if DEBUG + cli_putstr("\r\ninput-msg (post enc):\r\n"); + cli_hexdump_rev(&src, 2); + cli_hexdump_block(src, length_B, 4, 16); +#endif + rsa_i2osp(NULL, &x, out_length); + return 0; +} + +uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length, + const void* src, uint16_t length_B, + rsa_privatekey_t* key, const rsa_oaep_parameter_t *p, + const rsa_label_t* label, void* seed){ + +// cli_putstr("\r\n -->rsa_decrypt_oaep()"); uart_flush(0); + if(!label){ + label = &rsa_oaep_default_label; + } + if(!p){ + p = &rsa_oaep_default_parameter; + } + uint16_t x_len, data_len; + bigint_t x; + uint16_t hv_len = hfal_hash_getHashsize(p->hf)/8; + uint8_t label_hv[hv_len]; + uint16_t msg_len = bigint_get_first_set_bit(key->modulus) / 8 + 1; + uint16_t db_len = msg_len - hv_len - 1; + uint8_t maskbuffer[db_len>hv_len?db_len:hv_len]; + + uint8_t *seed_buffer = dest; + uint8_t *db_buffer = seed_buffer + hv_len; + + x_len = bigint_get_first_set_bit(key->modulus)/8; + memset(dest, 0, bigint_length_B(key->modulus) - length_B); + memcpy((uint8_t*)dest + bigint_length_B(key->modulus) - length_B, src, length_B); + +// cli_putc('a'); uart_flush(0); + + x.wordv = dest; + x.length_B = key->modulus->length_B; + x.info = 0; + bigint_adjust(&x); + + +// cli_putc('b'); uart_flush(0); + rsa_os2ip(&x, NULL, bigint_length_B(key->modulus)); +#if DEBUG + cli_putstr_P(PSTR("\r\n rsa decrypting ...")); +#endif + rsa_dec(&x, key); +#if DEBUG + cli_putstr_P(PSTR(" [done]")); +#endif + rsa_i2osp(NULL, &x, &data_len); + +// cli_putstr("\r\n msg (raw, pre-move):\r\n"); +// cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16); + + if(data_len > x_len){ + return 7; + } +/* + cli_putstr("\r\n moving some bytes; x_len = "); + cli_hexdump_rev(&x_len, 2); + cli_putstr(" data_len = "); + cli_hexdump_rev(&data_len, 2); + uart_flush(0); +*/ + if(x_len != data_len){ + memmove((uint8_t*)dest + x_len - data_len, dest, data_len); +// cli_putstr(" (oh, not dead yet?!)"); +// uart_flush(0); + memset(dest, 0, x_len - data_len); + } + + hfal_hash_mem(p->hf, label_hv, label->label, label->length_b); +/* + cli_putstr("\r\n msg (raw, pre-feistel):\r\n"); + cli_hexdump_block(seed_buffer, bigint_length_B(key->modulus), 4, 16); + uart_flush(0); +*/ + p->mgf(maskbuffer, db_buffer, db_len, hv_len, p->mgf_parameter); + memxor(seed_buffer, maskbuffer, hv_len); + p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter); + memxor(db_buffer, maskbuffer, db_len); + + if(memcmp(label_hv, db_buffer, hv_len)){ +// cli_putstr("\r\nDBG: DB:\r\n"); +// cli_hexdump_block(db_buffer, db_len, 4, 16); + return 2; + } + + uint16_t ps_len=0; + while(db_buffer[hv_len + ps_len++] == 0) + ; + + --ps_len; + if(db_buffer[hv_len + ps_len] != 1){ + return 3; + } + + if(seed){ + memcpy(seed, seed_buffer, hv_len); + } + + msg_len = db_len - hv_len - 1 - ps_len; + memmove(dest, db_buffer + hv_len + ps_len + 1, msg_len); + + *out_length = msg_len; + + return 0; +} + + diff --git a/rsa/rsaes_oaep.h b/rsa/rsaes_oaep.h new file mode 100644 index 0000000..8084653 --- /dev/null +++ b/rsa/rsaes_oaep.h @@ -0,0 +1,54 @@ +/* rsa_oaep.h */ +/* + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2012 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef RSA_OAEP_H_ +#define RSA_OAEP_H_ + +#include +#include "mgf1.h" + + +void mgf1(void* dest, const void* seed, uint16_t seed_len_B, uint16_t out_length_B, const mgf1_parameter_t* p); + + +typedef struct { + void (*mgf)(void* dst, const void* seed, uint16_t slen_B, uint16_t dstlen_B, const mgf1_parameter_t* p); + const hfdesc_t* hf; + mgf1_parameter_t* mgf_parameter; +} rsa_oaep_parameter_t; + +typedef struct { + uint16_t length_b; + const void* label; +} rsa_label_t; + +extern rsa_oaep_parameter_t rsa_oaep_default_parameter; +extern rsa_label_t rsa_oaep_default_label; + +uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length, + const void* src, uint16_t length_B, + rsa_publickey_t* key, const rsa_oaep_parameter_t *p, + const rsa_label_t* label, const void* seed); + +uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length, + const void* src, uint16_t length_B, + rsa_privatekey_t* key, const rsa_oaep_parameter_t *p, + const rsa_label_t* label, void* seed); + +#endif /* RSA_OAEP_H_ */ diff --git a/rsa/rsaes_pkcs1v15.c b/rsa/rsaes_pkcs1v15.c new file mode 100644 index 0000000..459c62b --- /dev/null +++ b/rsa/rsaes_pkcs1v15.c @@ -0,0 +1,137 @@ +/* rsa_pkcs1v15.c */ +/* + This file is part of the ARM-Crypto-Lib. + Copyright (C) 2006-2011 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include "bigint.h" +#include "rsa_basic.h" +#include "rsaes_pkcs1v15.h" + +#define DEBUG 0 + +#if DEBUG +#include "bigint_io.h" +#include "cli.h" +#endif + +#include "random_dummy.h" + +uint16_t rsa_pkcs1v15_compute_padlength_B(bigint_t* modulus, uint16_t msg_length_B){ + return bigint_get_first_set_bit(modulus) / 8 + 1 - msg_length_B - 3; +} + +uint8_t rsa_encrypt_pkcs1v15(void* dest, uint16_t* out_length, const void* src, + uint16_t length_B, rsa_publickey_t* key, const void* pad){ + int16_t pad_length; + bigint_t x; + pad_length = rsa_pkcs1v15_compute_padlength_B(key->modulus, length_B); + if(pad_length<8){ +#if DEBUG + cli_putstr_P(PSTR("\r\nERROR: pad_length<8; pad_length: ")); + cli_hexdump_rev(&pad_length, 2); +#endif + return 2; /* message to long */ + } + if(!pad){ +#if DEBUG + cli_putstr_P(PSTR("\r\nauto-generating pad ...")); +#endif + uint16_t i; + uint8_t c; + for(i=0; i=m_length){ + return 1; + } + ++idx; + while(((uint8_t*)x.wordv)[idx+pad_length]!=0 && (idx+pad_length)=m_length){ + return 2; + } + *out_length = m_length - idx - pad_length - 1; + if(pad){ +#if DEBUG + cli_putstr_P(PSTR("\r\npadding block:")); + cli_hexdump_block(((uint8_t*)x.wordv)+idx, pad_length, 4, 16); + cli_putstr_P(PSTR("\r\npad @ 0x")); + cli_hexdump_rev(&pad, 2); + cli_putstr_P(PSTR("\r\ndst @ 0x")); + cli_hexdump_rev(&dest, 2); +#endif + memcpy(pad, ((uint8_t*)x.wordv)+idx, pad_length); + } + memmove(dest, ((uint8_t*)x.wordv) + idx + pad_length + 1, m_length - idx - pad_length - 1); + + return 0; +} + diff --git a/rsa/rsaes_pkcs1v15.h b/rsa/rsaes_pkcs1v15.h new file mode 100644 index 0000000..cb12740 --- /dev/null +++ b/rsa/rsaes_pkcs1v15.h @@ -0,0 +1,35 @@ +/* rsa_pkcs1v15.h */ +/* + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2011 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef RSA_PKCS1V15_H_ +#define RSA_PKCS1V15_H_ + +#include +#include "bigint.h" + +uint16_t rsa_pkcs1v15_compute_padlength_B(bigint_t* modulus, uint16_t msg_length_B); + + +uint8_t rsa_encrypt_pkcs1v15(void* dest, uint16_t* out_length, const void* src, + uint16_t length_B, rsa_publickey_t* key, const void* pad); + +uint8_t rsa_decrypt_pkcs1v15(void* dest, uint16_t* out_length, const void* src, + uint16_t length_B, rsa_privatekey_t* key, void* pad); + +#endif /* RSA_PKCS1V15_H_ */ diff --git a/salsa20/salsa20.c b/salsa20/salsa20.c index 4e994db..95a38d5 100644 --- a/salsa20/salsa20.c +++ b/salsa20/salsa20.c @@ -111,31 +111,31 @@ void salsa20_genBlock128(void* dest, const void* k, const void* iv, uint64_t i){ void salsa20_init(void* key, uint16_t keylength_b, void* iv, salsa20_ctx_t* ctx){ if(keylength_b==256){ - memcpy_P((ctx->a+ 0), sigma+ 0, 4); - memcpy_P((ctx->a+20), sigma+ 4, 4); - memcpy_P((ctx->a+40), sigma+ 8, 4); - memcpy( (ctx->a+44), (uint8_t*)key+16, 16); - memcpy_P((ctx->a+60), sigma+12, 4); + memcpy_P((ctx->a.v8+ 0), sigma+ 0, 4); + memcpy_P((ctx->a.v8+20), sigma+ 4, 4); + memcpy_P((ctx->a.v8+40), sigma+ 8, 4); + memcpy( (ctx->a.v8+44), (uint8_t*)key+16, 16); + memcpy_P((ctx->a.v8+60), sigma+12, 4); }else{ - memcpy_P((ctx->a+ 0), theta+ 0, 4); - memcpy_P((ctx->a+20), theta+ 4, 4); - memcpy_P((ctx->a+40), theta+ 8, 4); - memcpy( (ctx->a+44), (uint8_t*)key+ 0, 16); - memcpy_P((ctx->a+60), theta+12, 4); + memcpy_P((ctx->a.v8+ 0), theta+ 0, 4); + memcpy_P((ctx->a.v8+20), theta+ 4, 4); + memcpy_P((ctx->a.v8+40), theta+ 8, 4); + memcpy( (ctx->a.v8+44), (uint8_t*)key+ 0, 16); + memcpy_P((ctx->a.v8+60), theta+12, 4); } - memcpy( (ctx->a+ 4), key, 16); - memset( (ctx->a+24), 0, 16); + memcpy( (ctx->a.v8+ 4), key, 16); + memset( (ctx->a.v8+24), 0, 16); if(iv){ - memcpy( (ctx->a+24), iv, 8); + memcpy( (ctx->a.v8+24), iv, 8); } ctx->buffer_idx=64; } uint8_t salsa20_gen(salsa20_ctx_t* ctx){ if(ctx->buffer_idx==64){ - memcpy(ctx->buffer, ctx->a, 64); + memcpy(ctx->buffer, ctx->a.v8, 64); salsa20_hash((uint32_t*)(ctx->buffer)); - *((uint64_t*)(ctx->a+32)) += 1; + ctx->a.v64[4] += 1; ctx->buffer_idx = 0; } return ctx->buffer[ctx->buffer_idx++]; diff --git a/salsa20/salsa20.h b/salsa20/salsa20.h index 29e7e81..fe33228 100644 --- a/salsa20/salsa20.h +++ b/salsa20/salsa20.h @@ -23,7 +23,10 @@ #include typedef struct{ - uint8_t a[64]; + union{ + uint8_t v8[64]; + uint64_t v64[ 8]; + } a; uint8_t buffer[64]; uint8_t buffer_idx; } salsa20_ctx_t; diff --git a/test_src/config.h b/test_src/config.h index b0d669e..0a985df 100644 --- a/test_src/config.h +++ b/test_src/config.h @@ -28,7 +28,9 @@ #include "uart_defs.h" #define UART0_I 1 +#ifndef UART0_BAUD_RATE #define UART0_BAUD_RATE 115200 +#endif #define UART0_PARATY UART_PARATY_NONE #define UART0_STOPBITS UART_STOPBITS_1 #define UART0_DATABITS UART_DATABITS_8 diff --git a/test_src/main-rsa_oaep-test.c b/test_src/main-rsa_oaep-test.c deleted file mode 100644 index 40ec9ad..0000000 --- a/test_src/main-rsa_oaep-test.c +++ /dev/null @@ -1,810 +0,0 @@ -/* main-dsa-test.c */ -/* - This file is part of the ARM-Crypto-Lib. - Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -/* - * RSA test-suit - * -*/ -#include "main-test-common.h" - -#include "noekeon.h" -#include "noekeon_prng.h" -#include "bigint.h" -#include "bigint_io.h" -#include "random_dummy.h" -#include "rsa_basic.h" -#include "rsa_oaep.h" - -#include "performance_test.h" - -const char* algo_name = "RSA-OAEP"; - -#define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)) -#define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t)) - -/***************************************************************************** - * additional validation-functions * - *****************************************************************************/ -#if 0 -/* ================================== - * Example 1: A 1024-bit RSA Key Pair - * ================================== */ - -/* ------------------------------ - * Components of the RSA Key Pair - * ------------------------------ */ - -/* RSA modulus n: */ -const uint8_t modulus[] = { -0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4, -0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab, -0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85, -0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72, -0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97, -0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14, -0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24, -0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb -}; - -/* RSA public exponent e: */ -const uint8_t public_exponent[] = { -0x00, 0x01, 0x00, 0x01 -}; - -/* RSA private exponent d: */ -const uint8_t private_exponent[] = { -0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c, -0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd, -0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b, -0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55, -0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73, -0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf, -0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde, -0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1 -}; - -/* Prime p: */ -const uint8_t p[] = { -0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b, -0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a, -0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1, -0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d -}; - -/* Prime q: */ -const uint8_t q[] = { -0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7, -0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c, -0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe, -0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77 -}; - -/* p's CRT exponent dP: */ -const uint8_t dp[] = { -0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04, -0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3, -0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d, -0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1 -}; - -/* q's CRT exponent dQ: */ -const uint8_t dq[] = { -0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc, -0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73, -0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a, -0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83 -}; - -/* CRT coefficient qInv: */ -const uint8_t qinv[] = { -0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d, -0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11, -0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81, -0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1 -}; - -/* --------------------------------- - * RSAES-OAEP Encryption Example 1.1 - * --------------------------------- */ - -/* Message to be, encrypted: */ -const uint8_t message[] = { -0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23, -0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34 -}; - -/* Seed: */ -const uint8_t seed[] = { -0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1, -0xdd, 0xa0, 0xa5, 0xef -}; - -/* Encryption: */ -const uint8_t encrypted[] = { -0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f, -0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb, -0x21, 0x69, 0x6d, 0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f, 0x8a, 0xfc, 0xc2, 0x01, -0x03, 0x5f, 0x7b, 0x6d, 0x8e, 0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a, 0x53, 0x5f, -0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f, 0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22, -0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70, 0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26, -0xd9, 0x8c, 0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94, 0xa0, 0xd9, 0xfa, 0x1e, 0x8c, -0x40, 0x24, 0x30, 0x9c, 0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a, 0xc7, 0x2e, 0x8a -}; - -/* Message to be encrypted: */ -const uint8_t message2[] = { -0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9, -0xba, 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, 0x9d, 0xd5 -}; - -/* Seed: */ -const uint8_t seed2[] = { -0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25, -0xfe, 0x4f, 0xe3, 0x5f -}; - -/* Encryption: */ -const uint8_t encrypted2[] = { -0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf, -0xf8, 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11, -0x65, 0x98, 0x8d, 0x4a, 0x27, 0x9e, 0x15, 0x77, 0xd7, 0x30, 0xfc, 0x7a, 0x29, 0x93, 0x2e, 0x3f, -0x00, 0xc8, 0x15, 0x15, 0x23, 0x6d, 0x8d, 0x8e, 0x31, 0x01, 0x7a, 0x7a, 0x09, 0xdf, 0x43, 0x52, -0xd9, 0x04, 0xcd, 0xeb, 0x79, 0xaa, 0x58, 0x3a, 0xdc, 0xc3, 0x1e, 0xa6, 0x98, 0xa4, 0xc0, 0x52, -0x83, 0xda, 0xba, 0x90, 0x89, 0xbe, 0x54, 0x91, 0xf6, 0x7c, 0x1a, 0x4e, 0xe4, 0x8d, 0xc7, 0x4b, -0xbb, 0xe6, 0x64, 0x3a, 0xef, 0x84, 0x66, 0x79, 0xb4, 0xcb, 0x39, 0x5a, 0x35, 0x2d, 0x5e, 0xd1, -0x15, 0x91, 0x2d, 0xf6, 0x96, 0xff, 0xe0, 0x70, 0x29, 0x32, 0x94, 0x6d, 0x71, 0x49, 0x2b, 0x44 -}; - -/**********************************************************************************************/ -/* --------------------------------- - * RSAES-OAEP Encryption Example 2.1 - * --------------------------------- */ - -/* Message to be encrypted: */ -const uint8_t message3[] = { -0x8f, 0xf0, 0x0c, 0xaa, 0x60, 0x5c, 0x70, 0x28, 0x30, 0x63, 0x4d, 0x9a, 0x6c, 0x3d, 0x42, 0xc6, -0x52, 0xb5, 0x8c, 0xf1, 0xd9, 0x2f, 0xec, 0x57, 0x0b, 0xee, 0xe7 -}; - -/* Seed: */ -const uint8_t seed3[] = { -0x8c, 0x40, 0x7b, 0x5e, 0xc2, 0x89, 0x9e, 0x50, 0x99, 0xc5, 0x3e, 0x8c, 0xe7, 0x93, 0xbf, 0x94, -0xe7, 0x1b, 0x17, 0x82 -}; - -/* Encryption: */ -const uint8_t encrypted3[] = { -0x01, 0x81, 0xaf, 0x89, 0x22, 0xb9, 0xfc, 0xb4, 0xd7, 0x9d, 0x92, 0xeb, 0xe1, 0x98, 0x15, 0x99, -0x2f, 0xc0, 0xc1, 0x43, 0x9d, 0x8b, 0xcd, 0x49, 0x13, 0x98, 0xa0, 0xf4, 0xad, 0x3a, 0x32, 0x9a, -0x5b, 0xd9, 0x38, 0x55, 0x60, 0xdb, 0x53, 0x26, 0x83, 0xc8, 0xb7, 0xda, 0x04, 0xe4, 0xb1, 0x2a, -0xed, 0x6a, 0xac, 0xdf, 0x47, 0x1c, 0x34, 0xc9, 0xcd, 0xa8, 0x91, 0xad, 0xdc, 0xc2, 0xdf, 0x34, -0x56, 0x65, 0x3a, 0xa6, 0x38, 0x2e, 0x9a, 0xe5, 0x9b, 0x54, 0x45, 0x52, 0x57, 0xeb, 0x09, 0x9d, -0x56, 0x2b, 0xbe, 0x10, 0x45, 0x3f, 0x2b, 0x6d, 0x13, 0xc5, 0x9c, 0x02, 0xe1, 0x0f, 0x1f, 0x8a, -0xbb, 0x5d, 0xa0, 0xd0, 0x57, 0x09, 0x32, 0xda, 0xcf, 0x2d, 0x09, 0x01, 0xdb, 0x72, 0x9d, 0x0f, -0xef, 0xcc, 0x05, 0x4e, 0x70, 0x96, 0x8e, 0xa5, 0x40, 0xc8, 0x1b, 0x04, 0xbc, 0xae, 0xfe, 0x72, -0x0e -}; -#endif -/**********************************************************************************************/ - -/* --------------------------------- - * RSAES-OAEP Encryption Example 2.4 - * --------------------------------- */ - -/* Message to be encrypted: */ -const uint8_t message4[] PROGMEM = { -0xa7, 0xeb, 0x2a, 0x50, 0x36, 0x93, 0x1d, 0x27, 0xd4, 0xe8, 0x91, 0x32, 0x6d, 0x99, 0x69, 0x2f, -0xfa, 0xdd, 0xa9, 0xbf, 0x7e, 0xfd, 0x3e, 0x34, 0xe6, 0x22, 0xc4, 0xad, 0xc0, 0x85, 0xf7, 0x21, -0xdf, 0xe8, 0x85, 0x07, 0x2c, 0x78, 0xa2, 0x03, 0xb1, 0x51, 0x73, 0x9b, 0xe5, 0x40, 0xfa, 0x8c, -0x15, 0x3a, 0x10, 0xf0, 0x0a -}; - -/* Seed: */ -const uint8_t seed4[] PROGMEM = { -0x9a, 0x7b, 0x3b, 0x0e, 0x70, 0x8b, 0xd9, 0x6f, 0x81, 0x90, 0xec, 0xab, 0x4f, 0xb9, 0xb2, 0xb3, -0x80, 0x5a, 0x81, 0x56 -}; - -/* Encryption: */ -const uint8_t encrypted4[] PROGMEM = { -/* 0x00,*/ 0xa4, 0x57, 0x8c, 0xbc, 0x17, 0x63, 0x18, 0xa6, 0x38, 0xfb, 0xa7, 0xd0, 0x1d, 0xf1, 0x57, -0x46, 0xaf, 0x44, 0xd4, 0xf6, 0xcd, 0x96, 0xd7, 0xe7, 0xc4, 0x95, 0xcb, 0xf4, 0x25, 0xb0, 0x9c, -0x64, 0x9d, 0x32, 0xbf, 0x88, 0x6d, 0xa4, 0x8f, 0xba, 0xf9, 0x89, 0xa2, 0x11, 0x71, 0x87, 0xca, -0xfb, 0x1f, 0xb5, 0x80, 0x31, 0x76, 0x90, 0xe3, 0xcc, 0xd4, 0x46, 0x92, 0x0b, 0x7a, 0xf8, 0x2b, -0x31, 0xdb, 0x58, 0x04, 0xd8, 0x7d, 0x01, 0x51, 0x4a, 0xcb, 0xfa, 0x91, 0x56, 0xe7, 0x82, 0xf8, -0x67, 0xf6, 0xbe, 0xd9, 0x44, 0x9e, 0x0e, 0x9a, 0x2c, 0x09, 0xbc, 0xec, 0xc6, 0xaa, 0x08, 0x76, -0x36, 0x96, 0x5e, 0x34, 0xb3, 0xec, 0x76, 0x6f, 0x2f, 0xe2, 0xe4, 0x30, 0x18, 0xa2, 0xfd, 0xde, -0xb1, 0x40, 0x61, 0x6a, 0x0e, 0x9d, 0x82, 0xe5, 0x33, 0x10, 0x24, 0xee, 0x06, 0x52, 0xfc, 0x76, -0x41 -}; - -/**********************************************************************************************/ -#if 1 -/* RSA modulus n: */ -const uint8_t modulus2[] PROGMEM = { -0x01, 0x94, 0x7c, 0x7f, 0xce, 0x90, 0x42, 0x5f, 0x47, 0x27, 0x9e, 0x70, 0x85, 0x1f, 0x25, 0xd5, -0xe6, 0x23, 0x16, 0xfe, 0x8a, 0x1d, 0xf1, 0x93, 0x71, 0xe3, 0xe6, 0x28, 0xe2, 0x60, 0x54, 0x3e, -0x49, 0x01, 0xef, 0x60, 0x81, 0xf6, 0x8c, 0x0b, 0x81, 0x41, 0x19, 0x0d, 0x2a, 0xe8, 0xda, 0xba, -0x7d, 0x12, 0x50, 0xec, 0x6d, 0xb6, 0x36, 0xe9, 0x44, 0xec, 0x37, 0x22, 0x87, 0x7c, 0x7c, 0x1d, -0x0a, 0x67, 0xf1, 0x4b, 0x16, 0x94, 0xc5, 0xf0, 0x37, 0x94, 0x51, 0xa4, 0x3e, 0x49, 0xa3, 0x2d, -0xde, 0x83, 0x67, 0x0b, 0x73, 0xda, 0x91, 0xa1, 0xc9, 0x9b, 0xc2, 0x3b, 0x43, 0x6a, 0x60, 0x05, -0x5c, 0x61, 0x0f, 0x0b, 0xaf, 0x99, 0xc1, 0xa0, 0x79, 0x56, 0x5b, 0x95, 0xa3, 0xf1, 0x52, 0x66, -0x32, 0xd1, 0xd4, 0xda, 0x60, 0xf2, 0x0e, 0xda, 0x25, 0xe6, 0x53, 0xc4, 0xf0, 0x02, 0x76, 0x6f, -0x45 -}; - -/* RSA public exponent e: */ -const uint8_t public_exponent2[] PROGMEM = { -0x01, 0x00, 0x01 -}; - -/* RSA private exponent d: */ -const uint8_t private_exponent2[] PROGMEM = { -0x08, 0x23, 0xf2, 0x0f, 0xad, 0xb5, 0xda, 0x89, 0x08, 0x8a, 0x9d, 0x00, 0x89, 0x3e, 0x21, 0xfa, -0x4a, 0x1b, 0x11, 0xfb, 0xc9, 0x3c, 0x64, 0xa3, 0xbe, 0x0b, 0xaa, 0xea, 0x97, 0xfb, 0x3b, 0x93, -0xc3, 0xff, 0x71, 0x37, 0x04, 0xc1, 0x9c, 0x96, 0x3c, 0x1d, 0x10, 0x7a, 0xae, 0x99, 0x05, 0x47, -0x39, 0xf7, 0x9e, 0x02, 0xe1, 0x86, 0xde, 0x86, 0xf8, 0x7a, 0x6d, 0xde, 0xfe, 0xa6, 0xd8, 0xcc, -0xd1, 0xd3, 0xc8, 0x1a, 0x47, 0xbf, 0xa7, 0x25, 0x5b, 0xe2, 0x06, 0x01, 0xa4, 0xa4, 0xb2, 0xf0, -0x8a, 0x16, 0x7b, 0x5e, 0x27, 0x9d, 0x71, 0x5b, 0x1b, 0x45, 0x5b, 0xdd, 0x7e, 0xab, 0x24, 0x59, -0x41, 0xd9, 0x76, 0x8b, 0x9a, 0xce, 0xfb, 0x3c, 0xcd, 0xa5, 0x95, 0x2d, 0xa3, 0xce, 0xe7, 0x25, -0x25, 0xb4, 0x50, 0x16, 0x63, 0xa8, 0xee, 0x15, 0xc9, 0xe9, 0x92, 0xd9, 0x24, 0x62, 0xfe, 0x39 -}; - -/* Prime p: */ -const uint8_t p2[] PROGMEM = { -0x01, 0x59, 0xdb, 0xde, 0x04, 0xa3, 0x3e, 0xf0, 0x6f, 0xb6, 0x08, 0xb8, 0x0b, 0x19, 0x0f, 0x4d, -0x3e, 0x22, 0xbc, 0xc1, 0x3a, 0xc8, 0xe4, 0xa0, 0x81, 0x03, 0x3a, 0xbf, 0xa4, 0x16, 0xed, 0xb0, -0xb3, 0x38, 0xaa, 0x08, 0xb5, 0x73, 0x09, 0xea, 0x5a, 0x52, 0x40, 0xe7, 0xdc, 0x6e, 0x54, 0x37, -0x8c, 0x69, 0x41, 0x4c, 0x31, 0xd9, 0x7d, 0xdb, 0x1f, 0x40, 0x6d, 0xb3, 0x76, 0x9c, 0xc4, 0x1a, -0x43 -}; - -/* Prime q: */ -const uint8_t q2[] PROGMEM = { -0x01, 0x2b, 0x65, 0x2f, 0x30, 0x40, 0x3b, 0x38, 0xb4, 0x09, 0x95, 0xfd, 0x6f, 0xf4, 0x1a, 0x1a, -0xcc, 0x8a, 0xda, 0x70, 0x37, 0x32, 0x36, 0xb7, 0x20, 0x2d, 0x39, 0xb2, 0xee, 0x30, 0xcf, 0xb4, -0x6d, 0xb0, 0x95, 0x11, 0xf6, 0xf3, 0x07, 0xcc, 0x61, 0xcc, 0x21, 0x60, 0x6c, 0x18, 0xa7, 0x5b, -0x8a, 0x62, 0xf8, 0x22, 0xdf, 0x03, 0x1b, 0xa0, 0xdf, 0x0d, 0xaf, 0xd5, 0x50, 0x6f, 0x56, 0x8b, -0xd7 -}; - -/* p's CRT exponent dP: */ -const uint8_t dp2[] PROGMEM = { -0x43, 0x6e, 0xf5, 0x08, 0xde, 0x73, 0x65, 0x19, 0xc2, 0xda, 0x4c, 0x58, 0x0d, 0x98, 0xc8, 0x2c, -0xb7, 0x45, 0x2a, 0x3f, 0xb5, 0xef, 0xad, 0xc3, 0xb9, 0xc7, 0x78, 0x9a, 0x1b, 0xc6, 0x58, 0x4f, -0x79, 0x5a, 0xdd, 0xbb, 0xd3, 0x24, 0x39, 0xc7, 0x46, 0x86, 0x55, 0x2e, 0xcb, 0x6c, 0x2c, 0x30, -0x7a, 0x4d, 0x3a, 0xf7, 0xf5, 0x39, 0xee, 0xc1, 0x57, 0x24, 0x8c, 0x7b, 0x31, 0xf1, 0xa2, 0x55 -}; - -/* q's CRT exponent dQ: */ -const uint8_t dq2[] PROGMEM = { -0x01, 0x2b, 0x15, 0xa8, 0x9f, 0x3d, 0xfb, 0x2b, 0x39, 0x07, 0x3e, 0x73, 0xf0, 0x2b, 0xdd, 0x0c, -0x1a, 0x7b, 0x37, 0x9d, 0xd4, 0x35, 0xf0, 0x5c, 0xdd, 0xe2, 0xef, 0xf9, 0xe4, 0x62, 0x94, 0x8b, -0x7c, 0xec, 0x62, 0xee, 0x90, 0x50, 0xd5, 0xe0, 0x81, 0x6e, 0x07, 0x85, 0xa8, 0x56, 0xb4, 0x91, -0x08, 0xdc, 0xb7, 0x5f, 0x36, 0x83, 0x87, 0x4d, 0x1c, 0xa6, 0x32, 0x9a, 0x19, 0x01, 0x30, 0x66, -0xff -}; - -/* CRT coefficient qInv: */ -const uint8_t qinv2[] PROGMEM = { -0x02, 0x70, 0xdb, 0x17, 0xd5, 0x91, 0x4b, 0x01, 0x8d, 0x76, 0x11, 0x8b, 0x24, 0x38, 0x9a, 0x73, -0x50, 0xec, 0x83, 0x6b, 0x00, 0x63, 0xa2, 0x17, 0x21, 0x23, 0x6f, 0xd8, 0xed, 0xb6, 0xd8, 0x9b, -0x51, 0xe7, 0xee, 0xb8, 0x7b, 0x61, 0x1b, 0x71, 0x32, 0xcb, 0x7e, 0xa7, 0x35, 0x6c, 0x23, 0x15, -0x1c, 0x1e, 0x77, 0x51, 0x50, 0x7c, 0x78, 0x6d, 0x9e, 0xe1, 0x79, 0x41, 0x70, 0xa8, 0xc8, 0xe8 -}; - -#endif -/**********************************************************************************************/ - - -uint8_t keys_allocated = 0; -rsa_publickey_t pub_key; -rsa_privatekey_t priv_key; - -#if 0 - #define MSG message - #define SEED seed - #define ENCRYPTED encrypted - #define MODULUS modulus - #define PUB_EXPONENT public_exponent - #define PRIV_EXPONENT private_exponent - #define P p - #define Q q - #define DP dp - #define DQ dq - #define QINV qinv -#else - #define MSG message4 - #define SEED seed4 - #define ENCRYPTED encrypted4 - #define MODULUS modulus2 - #define PUB_EXPONENT public_exponent2 - #define PRIV_EXPONENT private_exponent2 - #define P p2 - #define Q q2 - #define DP dp2 - #define DQ dq2 - #define QINV qinv2 -#endif - - -uint8_t convert_nibble(uint8_t c){ - if(c>='0' && c<='9'){ - return c - '0'; - } - c |= 'A' ^ 'a'; - if(c>='a' && c<='f'){ - return c - 'a' + 10; - } - return 0xff; -} - -const char *block_ignore_string=" \t\r\n,;"; -#define BUFFER_LIMIT 120 -uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){ - uint16_t counter = 0; - uint16_t c; - uint8_t v, tmp = 0, idx = 0; - if(!ignore_string){ - ignore_string = block_ignore_string; - } - while(counter < length){ - c = cli_getc(); - if(c > 0xff){ - return counter; - } - if(strchr(ignore_string, c)){ - continue; - } - v = convert_nibble(c); - if(v > 0x0f){ - return counter; - } - if(idx){ - ((uint8_t*)dst)[counter++] = (tmp << 4) | v; - idx = 0; - if(counter % (BUFFER_LIMIT/2) == 0){ - cli_putc('.'); - } - }else{ - tmp = v; - idx = 1; - } - } - return counter; -} - -uint16_t own_atou(const char* str){ - uint16_t r=0; - while(*str && *str >= '0' && *str <= '9'){ - r *= 10; - r += *str++ - '0'; - } - return r; -} - -uint8_t read_bigint(bigint_t* a, char* prompt){ - uint16_t read_length, actual_length; - uint8_t off; - uint8_t *buffer; - char read_int_str[18]; - cli_putstr(prompt); - cli_putstr_P(PSTR("\r\n length: ")); - cli_getsn(read_int_str, 16); - read_length = own_atou(read_int_str); - off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t); - buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)); - if(!buffer){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - cli_putstr_P(PSTR("\r\n data: ")); - memset(buffer, 0, sizeof(bigint_word_t)); - actual_length = read_os(buffer + off, read_length, NULL); - if(actual_length != read_length){ - cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!")); - free(buffer); - return 1; - } - a->wordv = (bigint_word_t*)buffer; - a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); - bigint_changeendianess(a); - bigint_adjust(a); - return 0; -} - -uint8_t pre_alloc_key_crt(void){ - uint8_t c; - pub_key.modulus = malloc(sizeof(bigint_t)); - if(!pub_key.modulus){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - priv_key.modulus = pub_key.modulus; - priv_key.n = 5; - priv_key.components = malloc(5 * sizeof(bigint_t*)); - if(!priv_key.components){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - pub_key.exponent = malloc(sizeof(bigint_t)); - if(!pub_key.exponent){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - for(c=0; c<5; ++c){ - priv_key.components[c] = malloc(sizeof(bigint_t)); - if(!priv_key.components[c]){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - } - return 0; -} - -void free_key(void){ - uint8_t c; - free(pub_key.modulus->wordv); - free(pub_key.exponent->wordv); - free(pub_key.modulus); - pub_key.modulus = priv_key.modulus = NULL; - free(pub_key.exponent); - pub_key.exponent = NULL; - for(c = 0; c < priv_key.n; ++c){ - free(priv_key.components[c]->wordv); - free(priv_key.components[c]); - } - free(priv_key.components); - priv_key.components = NULL; -} - -uint8_t read_key_crt(void){ - uint8_t r; - cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); - r = pre_alloc_key_crt(); - if(r) return r; - r = read_bigint(pub_key.modulus,"\r\n = module ="); - if(r) return r; - r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); - if(r) return r; - r = read_bigint(priv_key.components[0],"\r\n = p (first prime) ="); - if(r) return r; - r = read_bigint(priv_key.components[1],"\r\n = q (second prime) ="); - if(r) return r; - r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) ="); - if(r) return r; - r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) ="); - if(r) return r; - r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) ="); - return r; -} - -uint8_t read_key_conv(void){ - uint8_t r; - cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); - pub_key.modulus = malloc(sizeof(bigint_t)); - if(!pub_key.modulus){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - r = read_bigint(pub_key.modulus,"\r\n = module ="); - if(r) return r; - priv_key.modulus = pub_key.modulus; - priv_key.n = 1; - pub_key.exponent = malloc(sizeof(bigint_t)); - if(!pub_key.exponent){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - priv_key.components = malloc(sizeof(bigint_t*)); - if(!priv_key.components){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - priv_key.components[0] = malloc(sizeof(bigint_t)); - if(!priv_key.components[0]){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); - if(r) return r; - r = read_bigint(priv_key.components[0],"\r\n = private exponent ="); - return r; -} - -void load_priv_conventional(void){ - bigint_t *epriv; - epriv = malloc(sizeof(bigint_t)); - if(!epriv){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); - epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t)); - if(!epriv->wordv){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT)); - priv_key.components = malloc(sizeof(bigint_t*)); - priv_key.components[0] = epriv; - priv_key.n = 1; - bigint_changeendianess(epriv); - bigint_adjust(epriv); -} - - -void load_priv_crt_mono(void){ - bigint_t **v; - const uint8_t *bv[5] = {P,Q,DP,DQ,QINV}; - uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)}; - uint8_t i; - v = malloc(5 * sizeof(bigint_t)); - if(!v){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - priv_key.components = malloc(5*sizeof(bigint_t*)); - if(!priv_key.components){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - priv_key.n = 5; - for(i=0; i<5; ++i){ - v[i] = malloc(sizeof(bigint_t)); - v[i]->info = 0; - v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); - v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t)); - if(!v[i]->wordv){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - memcpy(v[i]->wordv, bv[i], sv[i]); - bigint_changeendianess(v[i]); - bigint_adjust(v[i]); - priv_key.components[i] = v[i]; - } -} - -uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){ - a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t); - a->wordv = malloc(BIGINT_CEIL(length_B)); - if(!a->wordv){ - cli_putstr_P(PSTR("\r\nOOM!\r\n")); - return 1; - } - memset(a->wordv, 0, sizeof(bigint_word_t)); - memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B); - a->info = 0; - bigint_changeendianess(a); - bigint_adjust(a); - return 0; -} - -void load_fix_rsa(void){ - if(keys_allocated){ - free_key(); - } - keys_allocated = 1; - - if(pre_alloc_key_crt()){ - cli_putstr_P(PSTR("\r\nOOM!\r\n")); - return; - } - - load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS)); - load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT)); - priv_key.n = 5; - load_bigint_from_os(priv_key.components[0], P, sizeof(P)); - load_bigint_from_os(priv_key.components[1], Q, sizeof(Q)); - load_bigint_from_os(priv_key.components[2], DP, sizeof(DP)); - load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ)); - load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV)); - -// load_priv_conventional(); -// load_priv_crt_mono(); -} - -void quick_test(void){ - uint8_t *ciphertext, *plaintext, rc; - uint8_t seed[sizeof(SEED)]; - uint16_t clen, plen; - ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t)); - plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t)); - memcpy_P(plaintext, MSG, sizeof(MSG)); - memcpy_P(seed, SEED, sizeof(SEED)); - cli_putstr_P(PSTR("\r\nplaintext:")); - cli_hexdump_block(plaintext, sizeof(MSG), 4, 8); - cli_putstr_P(PSTR("\r\nencrypting: ...")); - rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed); - if(rc){ - cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: ")); - cli_hexdump_byte(rc); - return; - - } - - cli_putstr_P(PSTR("\r\n\r\nciphertext:")); - cli_hexdump_block(ciphertext, clen, 4, 8); - if(clen!=sizeof(ENCRYPTED)){ - cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<")); - }else{ - if(memcmp_P(ciphertext, ENCRYPTED, clen)){ - cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<")); - }else{ - cli_putstr_P(PSTR("\r\n>>OK<<")); - } - } - - cli_putstr_P(PSTR("\r\ndecrypting: ...")); - rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL); - if(rc){ - cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: ")); - cli_hexdump_byte(rc); - return; - } - cli_putstr_P(PSTR("\r\n\r\nplaintext:")); - cli_hexdump_block(plaintext, plen, 4, 8); - - free(ciphertext); - free(plaintext); -} - -void run_seed_test(void){ - uint8_t *msg, *ciph, *msg_; - uint16_t msg_len, ciph_len, msg_len_; - uint8_t seed[20], seed_out[20]; - char read_int_str[18]; - cli_putstr_P(PSTR("\r\n== test with given seed ==")); - cli_putstr_P(PSTR("\r\n = message =")); - cli_putstr_P(PSTR("\r\n length: ")); - cli_getsn(read_int_str, 16); - msg_len = own_atou(read_int_str); - msg = malloc(msg_len); - if(!msg){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - ciph = malloc(bigint_length_B(pub_key.modulus)); - if(!ciph){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - msg_ = malloc(bigint_length_B(pub_key.modulus)); - if(!msg_){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - cli_putstr_P(PSTR("\r\n data: ")); - read_os(msg, msg_len, NULL); - cli_putstr_P(PSTR("\r\n seed (20 bytes): ")); - read_os(seed, 20, NULL); - - cli_putstr_P(PSTR("\r\n encrypting ...")); - rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed); - cli_putstr_P(PSTR("\r\n ciphertext:")); - cli_hexdump_block(ciph, ciph_len, 4, 16); - cli_putstr_P(PSTR("\r\n decrypting ... ")); - rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out); - cli_putstr_P(PSTR("[done]")); - if(msg_len != msg_len_){ - char tstr[16]; - cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length (")); - itoa(msg_len_, tstr, 10); - cli_putstr(tstr); - cli_putstr_P(PSTR(" instead of ")); - itoa(msg_len, tstr, 10); - cli_putstr(tstr); - cli_putc(')'); - goto end; - } - if(memcmp(msg, msg_, msg_len)){ - cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:")); - cli_hexdump_block(msg_, msg_len_, 4, 16); - cli_putstr_P(PSTR("\r\nreference:")); - cli_hexdump_block(msg, msg_len, 4, 16); - goto end; - } - - if(memcmp(seed, seed_out, 20)){ - cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:")); - cli_hexdump_block(seed_out, 20, 4, 16); - cli_putstr_P(PSTR("\r\nreference:")); - cli_hexdump_block(seed, 20, 4, 16); - goto end; - } - cli_putstr_P(PSTR("\r\n >>OK<<")); -end: - free(msg); - free(msg_); - free(ciph); -} - -void reset_prng(void){ - uint8_t buf[16]; - memset(buf, 0, 16); - random_seed(buf); - cli_putstr_P(PSTR("\r\nPRNG reset")); -} - -void rsa_init(void){ - prng_get_byte = random8; -} - -void load_key(void){ - if(keys_allocated){ - free_key(); - } - keys_allocated = 1; - read_key_crt(); -} - -void test_dump(void){ - char lstr[16]; - int len; - cli_putstr_P(PSTR("\r\nenter dump length: ")); - cli_getsn_cecho(lstr, 15); - len = own_atou(lstr); - cli_putstr_P(PSTR("\r\ndumping 0x")); - cli_hexdump_rev(&len, 2); - cli_putstr_P(PSTR(" byte:")); - cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8); -} - -/***************************************************************************** - * main * - *****************************************************************************/ - -const char echo_test_str[] PROGMEM = "echo-test"; -const char reset_prng_str[] PROGMEM = "reset-prng"; -const char load_key_str[] PROGMEM = "load-key"; -const char load_fix_key_str[] PROGMEM = "load-fix-key"; -const char quick_test_str[] PROGMEM = "quick-test"; -const char seed_test_str[] PROGMEM = "seed-test"; -const char dump_test_str[] PROGMEM = "dump-test"; -const char performance_str[] PROGMEM = "performance"; -const char echo_str[] PROGMEM = "echo"; - -const cmdlist_entry_t cmdlist[] PROGMEM = { - { reset_prng_str, NULL, reset_prng }, - { load_key_str, NULL, load_key }, - { load_fix_key_str, NULL, load_fix_rsa }, - { quick_test_str, NULL, quick_test }, - { seed_test_str, NULL, run_seed_test }, - { dump_test_str, NULL, test_dump }, -// { performance_str, NULL, testrun_performance_bigint }, - { echo_str, (void*)1, (void_fpt)echo_ctrl }, - { NULL, NULL, NULL } -}; - -void dump_sp(void){ - uint8_t x; - uint8_t *xa = &x; - cli_putstr_P(PSTR("\r\nstack pointer: ~")); - cli_hexdump_rev(&xa, 4); -} - -int main (void){ - main_setup(); - - for(;;){ - welcome_msg(algo_name); - rsa_init(); - cmd_interface(cmdlist); - } -} diff --git a/test_src/main-rsa_pkcs15-test.c b/test_src/main-rsa_pkcs15-test.c deleted file mode 100644 index 9d6471e..0000000 --- a/test_src/main-rsa_pkcs15-test.c +++ /dev/null @@ -1,672 +0,0 @@ -/* main-dsa-test.c */ -/* - This file is part of the ARM-Crypto-Lib. - Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -/* - * RSA test-suit - * -*/ -#include "main-test-common.h" - -#include "noekeon.h" -#include "noekeon_prng.h" -#include "bigint.h" -#include "bigint_io.h" -#include "random_dummy.h" -#include "rsa_basic.h" -#include "rsa_pkcs15.h" - -#include "performance_test.h" - -const char* algo_name = "RSA-PKCS15"; - -#define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)) -#define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t)) - -/***************************************************************************** - * additional validation-functions * - *****************************************************************************/ - -/* Modulus: */ -const uint8_t modulus[] PROGMEM = { -0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4, -0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab, -0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85, -0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72, -0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97, -0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14, -0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24, -0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb -}; - -/* Public exponent: */ -const uint8_t pub_exponent[] PROGMEM = { 0x01, 0x00, 0x01 }; - -/* Exponent: */ -const uint8_t priv_exponent[] PROGMEM = { -0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c, -0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd, -0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b, -0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55, -0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73, -0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf, -0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde, -0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1 -}; - -/* Prime 1: */ -const uint8_t p[] PROGMEM = { -0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b, -0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a, -0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1, -0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d -}; - -/* Prime 2: */ -const uint8_t q[] PROGMEM = { -0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7, -0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c, -0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe, -0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77 -}; - -/* Prime exponent 1: */ -const uint8_t dp[] PROGMEM = { -0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04, -0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3, -0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d, -0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1 -}; - -/* Prime exponent 2: */ -const uint8_t dq[] PROGMEM = { -0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc, -0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73, -0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a, -0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83 -}; - -/* Coefficient: */ -const uint8_t qinv[] PROGMEM = { -0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d, -0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11, -0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81, -0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1 -}; - -/* PKCS#1 v1.5 encryption of 0x20, random messages with random s0xee,ds - * --------------------------------------------------------------------------- - */ - -/* Message: */ -const uint8_t message_x[] PROGMEM = { -0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23, -0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34 -}; - -/* Seed: */ -const uint8_t seed_x[] PROGMEM = { -0x01, 0x73, 0x41, 0xae, 0x38, 0x75, 0xd5, 0xf8, 0x71, 0x01, 0xf8, 0xcc, 0x4f, 0xa9, 0xb9, 0xbc, -0x15, 0x6b, 0xb0, 0x46, 0x28, 0xfc, 0xcd, 0xb2, 0xf4, 0xf1, 0x1e, 0x90, 0x5b, 0xd3, 0xa1, 0x55, -0xd3, 0x76, 0xf5, 0x93, 0xbd, 0x73, 0x04, 0x21, 0x08, 0x74, 0xeb, 0xa0, 0x8a, 0x5e, 0x22, 0xbc, -0xcc, 0xb4, 0xc9, 0xd3, 0x88, 0x2a, 0x93, 0xa5, 0x4d, 0xb0, 0x22, 0xf5, 0x03, 0xd1, 0x63, 0x38, -0xb6, 0xb7, 0xce, 0x16, 0xdc, 0x7f, 0x4b, 0xbf, 0x9a, 0x96, 0xb5, 0x97, 0x72, 0xd6, 0x60, 0x6e, -0x97, 0x47, 0xc7, 0x64, 0x9b, 0xf9, 0xe0, 0x83, 0xdb, 0x98, 0x18, 0x84, 0xa9, 0x54, 0xab, 0x3c, -0x6f }; - -/* Encryption: */ -const uint8_t encrypted_x[] PROGMEM = { -0x50, 0xb4, 0xc1, 0x41, 0x36, 0xbd, 0x19, 0x8c, 0x2f, 0x3c, 0x3e, 0xd2, 0x43, 0xfc, 0xe0, 0x36, -0xe1, 0x68, 0xd5, 0x65, 0x17, 0x98, 0x4a, 0x26, 0x3c, 0xd6, 0x64, 0x92, 0xb8, 0x08, 0x04, 0xf1, -0x69, 0xd2, 0x10, 0xf2, 0xb9, 0xbd, 0xfb, 0x48, 0xb1, 0x2f, 0x9e, 0xa0, 0x50, 0x09, 0xc7, 0x7d, -0xa2, 0x57, 0xcc, 0x60, 0x0c, 0xce, 0xfe, 0x3a, 0x62, 0x83, 0x78, 0x9d, 0x8e, 0xa0, 0xe6, 0x07, -0xac, 0x58, 0xe2, 0x69, 0x0e, 0xc4, 0xeb, 0xc1, 0x01, 0x46, 0xe8, 0xcb, 0xaa, 0x5e, 0xd4, 0xd5, -0xcc, 0xe6, 0xfe, 0x7b, 0x0f, 0xf9, 0xef, 0xc1, 0xea, 0xbb, 0x56, 0x4d, 0xbf, 0x49, 0x82, 0x85, -0xf4, 0x49, 0xee, 0x61, 0xdd, 0x7b, 0x42, 0xee, 0x5b, 0x58, 0x92, 0xcb, 0x90, 0x60, 0x1f, 0x30, -0xcd, 0xa0, 0x7b, 0xf2, 0x64, 0x89, 0x31, 0x0b, 0xcd, 0x23, 0xb5, 0x28, 0xce, 0xab, 0x3c, 0x31 -}; - -uint8_t keys_allocated = 0; -rsa_publickey_t pub_key; -rsa_privatekey_t priv_key; - -#if 1 - #define MSG message_x - #define SEED seed_x - #define ENCRYPTED encrypted_x - #define MODULUS modulus - #define PUB_EXPONENT pub_exponent - #define PRIV_EXPONENT priv_exponent - #define P p - #define Q q - #define DP dp - #define DQ dq - #define QINV qinv -#endif - - -uint8_t convert_nibble(uint8_t c){ - if(c>='0' && c<='9'){ - return c - '0'; - } - c |= 'A' ^ 'a'; - if(c>='a' && c<='f'){ - return c - 'a' + 10; - } - return 0xff; -} - -const char *block_ignore_string=" \t\r\n,;"; -#define BUFFER_LIMIT 120 -uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){ - uint16_t counter = 0; - uint16_t c; - uint8_t v, tmp = 0, idx = 0; - if(!ignore_string){ - ignore_string = block_ignore_string; - } - while(counter < length){ - c = cli_getc(); - if(c > 0xff){ - return counter; - } - if(strchr(ignore_string, c)){ - continue; - } - v = convert_nibble(c); - if(v > 0x0f){ - return counter; - } - if(idx){ - ((uint8_t*)dst)[counter++] = (tmp << 4) | v; - idx = 0; - if(counter % (BUFFER_LIMIT/2) == 0){ - cli_putc('.'); - } - }else{ - tmp = v; - idx = 1; - } - } - return counter; -} - -uint16_t own_atou(const char* str){ - uint16_t r=0; - while(*str && *str >= '0' && *str <= '9'){ - r *= 10; - r += *str++ - '0'; - } - return r; -} - -uint8_t read_bigint(bigint_t* a, char* prompt){ - uint16_t read_length, actual_length; - uint8_t off; - uint8_t *buffer; - char read_int_str[18]; - cli_putstr(prompt); - cli_putstr_P(PSTR("\r\n length: ")); - cli_getsn(read_int_str, 16); - read_length = own_atou(read_int_str); - off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t); - buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)); - if(!buffer){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - cli_putstr_P(PSTR("\r\n data: ")); - memset(buffer, 0, sizeof(bigint_word_t)); - actual_length = read_os(buffer + off, read_length, NULL); - if(actual_length != read_length){ - cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!")); - free(buffer); - return 1; - } - a->wordv = (bigint_word_t*)buffer; - a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); - bigint_changeendianess(a); - bigint_adjust(a); - return 0; -} - -uint8_t pre_alloc_key_crt(void){ - uint8_t c; - pub_key.modulus = malloc(sizeof(bigint_t)); - if(!pub_key.modulus){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - priv_key.modulus = pub_key.modulus; - priv_key.n = 5; - priv_key.components = malloc(5 * sizeof(bigint_t*)); - if(!priv_key.components){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - pub_key.exponent = malloc(sizeof(bigint_t)); - if(!pub_key.exponent){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - for(c=0; c<5; ++c){ - priv_key.components[c] = malloc(sizeof(bigint_t)); - if(!priv_key.components[c]){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - } - return 0; -} - -void free_key(void){ - uint8_t c; - free(pub_key.modulus->wordv); - free(pub_key.exponent->wordv); - free(pub_key.modulus); - pub_key.modulus = priv_key.modulus = NULL; - free(pub_key.exponent); - pub_key.exponent = NULL; - for(c = 0; c < priv_key.n; ++c){ - free(priv_key.components[c]->wordv); - free(priv_key.components[c]); - } - free(priv_key.components); - priv_key.components = NULL; -} - -uint8_t read_key_crt(void){ - uint8_t r; - cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); - r = pre_alloc_key_crt(); - if(r) return r; - r = read_bigint(pub_key.modulus,"\r\n = module ="); - if(r) return r; - r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); - if(r) return r; - r = read_bigint(priv_key.components[0],"\r\n = p (first prime) ="); - if(r) return r; - r = read_bigint(priv_key.components[1],"\r\n = q (second prime) ="); - if(r) return r; - r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) ="); - if(r) return r; - r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) ="); - if(r) return r; - r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) ="); -/* - cli_putstr_P(PSTR("\r\nmodulus:")); - bigint_print_hex(pub_key.modulus); - cli_putstr_P(PSTR("\r\npublic exponent:")); - bigint_print_hex(pub_key.exponent); - cli_putstr_P(PSTR("\r\np:")); - bigint_print_hex(priv_key.components[0]); - cli_putstr_P(PSTR("\r\nq:")); - bigint_print_hex(priv_key.components[1]); - cli_putstr_P(PSTR("\r\ndP:")); - bigint_print_hex(priv_key.components[2]); - cli_putstr_P(PSTR("\r\ndQ:")); - bigint_print_hex(priv_key.components[3]); - cli_putstr_P(PSTR("\r\nqInv:")); - bigint_print_hex(priv_key.components[4]); -*/ - return r; -} - -uint8_t read_key_conv(void){ - uint8_t r; - cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); - pub_key.modulus = malloc(sizeof(bigint_t)); - if(!pub_key.modulus){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - r = read_bigint(pub_key.modulus,"\r\n = module ="); - if(r) return r; - priv_key.modulus = pub_key.modulus; - priv_key.n = 1; - pub_key.exponent = malloc(sizeof(bigint_t)); - if(!pub_key.exponent){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - priv_key.components = malloc(sizeof(bigint_t*)); - if(!priv_key.components){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - priv_key.components[0] = malloc(sizeof(bigint_t)); - if(!priv_key.components[0]){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return 2; - } - r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); - if(r) return r; - r = read_bigint(priv_key.components[0],"\r\n = private exponent ="); - return r; -} - -void load_priv_conventional(void){ - bigint_t *epriv; - epriv = malloc(sizeof(bigint_t)); - if(!epriv){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); - epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t)); - if(!epriv->wordv){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT)); - priv_key.components = malloc(sizeof(bigint_t*)); - priv_key.components[0] = epriv; - priv_key.n = 1; - bigint_changeendianess(epriv); - bigint_adjust(epriv); -} - - -void load_priv_crt_mono(void){ - bigint_t **v; - const uint8_t *bv[5] = {P,Q,DP,DQ,QINV}; - uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)}; - uint8_t i; - v = malloc(5 * sizeof(bigint_t)); - if(!v){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - priv_key.components = malloc(5*sizeof(bigint_t*)); - if(!priv_key.components){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - priv_key.n = 5; - for(i=0; i<5; ++i){ - v[i] = malloc(sizeof(bigint_t)); - v[i]->info = 0; - v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); - v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t)); - if(!v[i]->wordv){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - memcpy(v[i]->wordv, bv[i], sv[i]); - bigint_changeendianess(v[i]); - bigint_adjust(v[i]); - priv_key.components[i] = v[i]; - } -} - -uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){ - a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t); - a->wordv = malloc(BIGINT_CEIL(length_B)); - if(!a->wordv){ - cli_putstr_P(PSTR("\r\nOOM!\r\n")); - return 1; - } - memset(a->wordv, 0, sizeof(bigint_word_t)); - memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B); - a->info = 0; - bigint_changeendianess(a); - bigint_adjust(a); - return 0; -} - -void load_fix_rsa(void){ - if(keys_allocated){ - free_key(); - } - keys_allocated = 1; - - if(pre_alloc_key_crt()){ - cli_putstr_P(PSTR("\r\nOOM!\r\n")); - return; - } - - load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS)); - load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT)); - priv_key.n = 5; - load_bigint_from_os(priv_key.components[0], P, sizeof(P)); - load_bigint_from_os(priv_key.components[1], Q, sizeof(Q)); - load_bigint_from_os(priv_key.components[2], DP, sizeof(DP)); - load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ)); - load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV)); - -// load_priv_conventional(); -// load_priv_crt_mono(); -} - -void quick_test(void){ - uint8_t *ciphertext, *plaintext, rc; - uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)]; - uint16_t clen, plen; - if(!keys_allocated){ - load_fix_rsa(); - } - ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t)); - plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t)); - memcpy_P(plaintext, MSG, sizeof(MSG)); - memcpy_P(seed, SEED, sizeof(SEED)); - cli_putstr_P(PSTR("\r\nplaintext:")); - cli_hexdump_block(plaintext, sizeof(MSG), 4, 16); - cli_putstr_P(PSTR("\r\nseed:")); - cli_hexdump_block(seed, sizeof(SEED), 4, 16); - cli_putstr_P(PSTR("\r\nencrypting: ...")); - - rc = rsa_encrypt_pkcs15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed); - if(rc){ - cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_pkcs15 returned: ")); - cli_hexdump_byte(rc); - return; - - } - - cli_putstr_P(PSTR("\r\n\r\nciphertext:")); - cli_hexdump_block(ciphertext, clen, 4, 16); - if(clen!=sizeof(ENCRYPTED)){ - cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<")); - }else{ - if(memcmp_P(ciphertext, ENCRYPTED, clen)){ - cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<")); - }else{ - cli_putstr_P(PSTR("\r\n>>OK<<")); - } - } - - cli_putstr_P(PSTR("\r\ndecrypting: ...")); - rc = rsa_decrypt_pkcs15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out); - if(rc){ - cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs15 returned: ")); - cli_hexdump_byte(rc); - return; - } - cli_putstr_P(PSTR("\r\n\r\nplaintext:")); - cli_hexdump_block(plaintext, plen, 4, 16); - cli_putstr_P(PSTR("\r\n\r\nseed (out):")); - cli_hexdump_block(seed_out, sizeof(SEED), 4, 16); - - free(ciphertext); - free(plaintext); -} - -void run_seed_test(void){ - uint8_t *msg, *ciph, *msg_; - uint16_t msg_len, ciph_len, msg_len_; - uint16_t seed_len; - uint8_t *seed, *seed_out; - char read_int_str[18]; - cli_putstr_P(PSTR("\r\n== test with given seed ==")); - cli_putstr_P(PSTR("\r\n = message =")); - cli_putstr_P(PSTR("\r\n length: ")); - cli_getsn(read_int_str, 16); - msg_len = own_atou(read_int_str); - seed_len = rsa_pkcs15_compute_padlength_B(pub_key.modulus, msg_len); - seed = malloc(seed_len); - if(!seed){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - seed_out = malloc(seed_len); - if(!seed_out){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - msg = malloc(msg_len); - if(!msg){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - ciph = malloc(bigint_length_B(pub_key.modulus)); - if(!ciph){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - msg_ = malloc(bigint_length_B(pub_key.modulus)); - if(!msg_){ - cli_putstr_P(PSTR("\r\nERROR: OOM!")); - return; - } - cli_putstr_P(PSTR("\r\n data: ")); - read_os(msg, msg_len, NULL); - cli_putstr_P(PSTR("\r\n seed (0x")); - cli_hexdump_rev(&seed_len, 2); - cli_putstr_P(PSTR(" bytes): ")); - read_os(seed, seed_len, NULL); - - cli_putstr_P(PSTR("\r\n encrypting ...")); -/* - cli_putstr_P(PSTR("\r\n plaintext:")); - cli_hexdump_block(msg, msg_len, 4, 16); - cli_putstr_P(PSTR("\r\n seed:")); - cli_hexdump_block(seed, seed_len, 4, 16); -*/ - rsa_encrypt_pkcs15(ciph, &ciph_len, msg, msg_len, &pub_key, seed); - cli_putstr_P(PSTR("\r\n ciphertext:")); - cli_hexdump_block(ciph, ciph_len, 4, 16); - cli_putstr_P(PSTR("\r\n decrypting ... ")); - rsa_decrypt_pkcs15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out); - cli_putstr_P(PSTR("[done]")); - if(msg_len != msg_len_){ - char tstr[16]; - cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length (")); - itoa(msg_len_, tstr, 10); - cli_putstr(tstr); - cli_putstr_P(PSTR(" instead of ")); - itoa(msg_len, tstr, 10); - cli_putstr(tstr); - cli_putc(')'); - goto end; - } - if(memcmp(msg, msg_, msg_len)){ - cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:")); - cli_hexdump_block(msg_, msg_len_, 4, 16); - cli_putstr_P(PSTR("\r\nreference:")); - cli_hexdump_block(msg, msg_len, 4, 16); - goto end; - } - - if(memcmp(seed, seed_out, seed_len)){ - cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:")); - cli_hexdump_block(seed_out, seed_len, 4, 16); - cli_putstr_P(PSTR("\r\nreference:")); - cli_hexdump_block(seed, seed_len, 4, 16); - goto end; - } - cli_putstr_P(PSTR("\r\n >>OK<<")); -end: - free(ciph); - free(msg_); - free(msg); - free(seed_out); - free(seed); -} - -void reset_prng(void){ - uint8_t buf[16]; - memset(buf, 0, 16); - random_seed(buf); - cli_putstr_P(PSTR("\r\nPRNG reset")); -} - -void rsa_init(void){ - prng_get_byte = random8; -} - -void load_key(void){ - if(keys_allocated){ - free_key(); - } - keys_allocated = 1; - read_key_crt(); -} - -void test_dump(void){ - char lstr[16]; - int len; - cli_putstr_P(PSTR("\r\nenter dump length: ")); - cli_getsn_cecho(lstr, 15); - len = own_atou(lstr); - cli_putstr_P(PSTR("\r\ndumping 0x")); - cli_hexdump_rev(&len, 2); - cli_putstr_P(PSTR(" byte:")); - cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8); -} - -/***************************************************************************** - * main * - *****************************************************************************/ - -const char echo_test_str[] PROGMEM = "echo-test"; -const char reset_prng_str[] PROGMEM = "reset-prng"; -const char load_key_str[] PROGMEM = "load-key"; -const char load_fix_key_str[] PROGMEM = "load-fix-key"; -const char quick_test_str[] PROGMEM = "quick-test"; -const char seed_test_str[] PROGMEM = "seed-test"; -const char dump_test_str[] PROGMEM = "dump-test"; -const char performance_str[] PROGMEM = "performance"; -const char echo_str[] PROGMEM = "echo"; - -const cmdlist_entry_t cmdlist[] PROGMEM = { - { reset_prng_str, NULL, reset_prng }, - { load_key_str, NULL, load_key }, - { load_fix_key_str, NULL, load_fix_rsa }, - { quick_test_str, NULL, quick_test }, - { seed_test_str, NULL, run_seed_test }, - { dump_test_str, NULL, test_dump }, -// { performance_str, NULL, testrun_performance_bigint }, - { echo_str, (void*)1, (void_fpt)echo_ctrl }, - { NULL, NULL, NULL } -}; - -void dump_sp(void){ - uint8_t x; - uint8_t *xa = &x; - cli_putstr_P(PSTR("\r\nstack pointer: ~")); - cli_hexdump_rev(&xa, 4); -} - -int main (void){ - main_setup(); - - for(;;){ - welcome_msg(algo_name); - rsa_init(); - cmd_interface(cmdlist); - } -} diff --git a/test_src/main-rsaes_oaep-test.c b/test_src/main-rsaes_oaep-test.c new file mode 100644 index 0000000..f319975 --- /dev/null +++ b/test_src/main-rsaes_oaep-test.c @@ -0,0 +1,811 @@ +/* main-dsa-test.c */ +/* + This file is part of the ARM-Crypto-Lib. + Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + * RSA test-suit + * +*/ +#include "main-test-common.h" + +#include "noekeon.h" +#include "noekeon_prng.h" +#include "bigint.h" +#include "bigint_io.h" +#include "random_dummy.h" +#include "rsa_basic.h" +#include "rsaes_oaep.h" + +#include "performance_test.h" + +const char* algo_name = "RSAES-OAEP"; + +#define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)) +#define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t)) + +/***************************************************************************** + * additional validation-functions * + *****************************************************************************/ +#if 0 +/* ================================== + * Example 1: A 1024-bit RSA Key Pair + * ================================== */ + +/* ------------------------------ + * Components of the RSA Key Pair + * ------------------------------ */ + +/* RSA modulus n: */ +const uint8_t modulus[] = { +0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4, +0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab, +0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85, +0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72, +0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97, +0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14, +0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24, +0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb +}; + +/* RSA public exponent e: */ +const uint8_t public_exponent[] = { +0x00, 0x01, 0x00, 0x01 +}; + +/* RSA private exponent d: */ +const uint8_t private_exponent[] = { +0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c, +0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd, +0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b, +0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55, +0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73, +0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf, +0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde, +0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1 +}; + +/* Prime p: */ +const uint8_t p[] = { +0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b, +0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a, +0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1, +0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d +}; + +/* Prime q: */ +const uint8_t q[] = { +0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7, +0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c, +0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe, +0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77 +}; + +/* p's CRT exponent dP: */ +const uint8_t dp[] = { +0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04, +0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3, +0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d, +0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1 +}; + +/* q's CRT exponent dQ: */ +const uint8_t dq[] = { +0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc, +0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73, +0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a, +0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83 +}; + +/* CRT coefficient qInv: */ +const uint8_t qinv[] = { +0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d, +0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11, +0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81, +0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1 +}; + +/* --------------------------------- + * RSAES-OAEP Encryption Example 1.1 + * --------------------------------- */ + +/* Message to be, encrypted: */ +const uint8_t message[] = { +0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23, +0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34 +}; + +/* Seed: */ +const uint8_t seed[] = { +0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1, +0xdd, 0xa0, 0xa5, 0xef +}; + +/* Encryption: */ +const uint8_t encrypted[] = { +0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f, +0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb, +0x21, 0x69, 0x6d, 0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f, 0x8a, 0xfc, 0xc2, 0x01, +0x03, 0x5f, 0x7b, 0x6d, 0x8e, 0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a, 0x53, 0x5f, +0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f, 0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22, +0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70, 0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26, +0xd9, 0x8c, 0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94, 0xa0, 0xd9, 0xfa, 0x1e, 0x8c, +0x40, 0x24, 0x30, 0x9c, 0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a, 0xc7, 0x2e, 0x8a +}; + +/* Message to be encrypted: */ +const uint8_t message2[] = { +0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9, +0xba, 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, 0x9d, 0xd5 +}; + +/* Seed: */ +const uint8_t seed2[] = { +0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25, +0xfe, 0x4f, 0xe3, 0x5f +}; + +/* Encryption: */ +const uint8_t encrypted2[] = { +0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf, +0xf8, 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11, +0x65, 0x98, 0x8d, 0x4a, 0x27, 0x9e, 0x15, 0x77, 0xd7, 0x30, 0xfc, 0x7a, 0x29, 0x93, 0x2e, 0x3f, +0x00, 0xc8, 0x15, 0x15, 0x23, 0x6d, 0x8d, 0x8e, 0x31, 0x01, 0x7a, 0x7a, 0x09, 0xdf, 0x43, 0x52, +0xd9, 0x04, 0xcd, 0xeb, 0x79, 0xaa, 0x58, 0x3a, 0xdc, 0xc3, 0x1e, 0xa6, 0x98, 0xa4, 0xc0, 0x52, +0x83, 0xda, 0xba, 0x90, 0x89, 0xbe, 0x54, 0x91, 0xf6, 0x7c, 0x1a, 0x4e, 0xe4, 0x8d, 0xc7, 0x4b, +0xbb, 0xe6, 0x64, 0x3a, 0xef, 0x84, 0x66, 0x79, 0xb4, 0xcb, 0x39, 0x5a, 0x35, 0x2d, 0x5e, 0xd1, +0x15, 0x91, 0x2d, 0xf6, 0x96, 0xff, 0xe0, 0x70, 0x29, 0x32, 0x94, 0x6d, 0x71, 0x49, 0x2b, 0x44 +}; + +/**********************************************************************************************/ +/* --------------------------------- + * RSAES-OAEP Encryption Example 2.1 + * --------------------------------- */ + +/* Message to be encrypted: */ +const uint8_t message3[] = { +0x8f, 0xf0, 0x0c, 0xaa, 0x60, 0x5c, 0x70, 0x28, 0x30, 0x63, 0x4d, 0x9a, 0x6c, 0x3d, 0x42, 0xc6, +0x52, 0xb5, 0x8c, 0xf1, 0xd9, 0x2f, 0xec, 0x57, 0x0b, 0xee, 0xe7 +}; + +/* Seed: */ +const uint8_t seed3[] = { +0x8c, 0x40, 0x7b, 0x5e, 0xc2, 0x89, 0x9e, 0x50, 0x99, 0xc5, 0x3e, 0x8c, 0xe7, 0x93, 0xbf, 0x94, +0xe7, 0x1b, 0x17, 0x82 +}; + +/* Encryption: */ +const uint8_t encrypted3[] = { +0x01, 0x81, 0xaf, 0x89, 0x22, 0xb9, 0xfc, 0xb4, 0xd7, 0x9d, 0x92, 0xeb, 0xe1, 0x98, 0x15, 0x99, +0x2f, 0xc0, 0xc1, 0x43, 0x9d, 0x8b, 0xcd, 0x49, 0x13, 0x98, 0xa0, 0xf4, 0xad, 0x3a, 0x32, 0x9a, +0x5b, 0xd9, 0x38, 0x55, 0x60, 0xdb, 0x53, 0x26, 0x83, 0xc8, 0xb7, 0xda, 0x04, 0xe4, 0xb1, 0x2a, +0xed, 0x6a, 0xac, 0xdf, 0x47, 0x1c, 0x34, 0xc9, 0xcd, 0xa8, 0x91, 0xad, 0xdc, 0xc2, 0xdf, 0x34, +0x56, 0x65, 0x3a, 0xa6, 0x38, 0x2e, 0x9a, 0xe5, 0x9b, 0x54, 0x45, 0x52, 0x57, 0xeb, 0x09, 0x9d, +0x56, 0x2b, 0xbe, 0x10, 0x45, 0x3f, 0x2b, 0x6d, 0x13, 0xc5, 0x9c, 0x02, 0xe1, 0x0f, 0x1f, 0x8a, +0xbb, 0x5d, 0xa0, 0xd0, 0x57, 0x09, 0x32, 0xda, 0xcf, 0x2d, 0x09, 0x01, 0xdb, 0x72, 0x9d, 0x0f, +0xef, 0xcc, 0x05, 0x4e, 0x70, 0x96, 0x8e, 0xa5, 0x40, 0xc8, 0x1b, 0x04, 0xbc, 0xae, 0xfe, 0x72, +0x0e +}; +#endif +/**********************************************************************************************/ + +/* --------------------------------- + * RSAES-OAEP Encryption Example 2.4 + * --------------------------------- */ + +/* Message to be encrypted: */ +const uint8_t message4[] PROGMEM = { +0xa7, 0xeb, 0x2a, 0x50, 0x36, 0x93, 0x1d, 0x27, 0xd4, 0xe8, 0x91, 0x32, 0x6d, 0x99, 0x69, 0x2f, +0xfa, 0xdd, 0xa9, 0xbf, 0x7e, 0xfd, 0x3e, 0x34, 0xe6, 0x22, 0xc4, 0xad, 0xc0, 0x85, 0xf7, 0x21, +0xdf, 0xe8, 0x85, 0x07, 0x2c, 0x78, 0xa2, 0x03, 0xb1, 0x51, 0x73, 0x9b, 0xe5, 0x40, 0xfa, 0x8c, +0x15, 0x3a, 0x10, 0xf0, 0x0a +}; + +/* Seed: */ +const uint8_t seed4[] PROGMEM = { +0x9a, 0x7b, 0x3b, 0x0e, 0x70, 0x8b, 0xd9, 0x6f, 0x81, 0x90, 0xec, 0xab, 0x4f, 0xb9, 0xb2, 0xb3, +0x80, 0x5a, 0x81, 0x56 +}; + +/* Encryption: */ +const uint8_t encrypted4[] PROGMEM = { +/* 0x00,*/ 0xa4, 0x57, 0x8c, 0xbc, 0x17, 0x63, 0x18, 0xa6, 0x38, 0xfb, 0xa7, 0xd0, 0x1d, 0xf1, 0x57, +0x46, 0xaf, 0x44, 0xd4, 0xf6, 0xcd, 0x96, 0xd7, 0xe7, 0xc4, 0x95, 0xcb, 0xf4, 0x25, 0xb0, 0x9c, +0x64, 0x9d, 0x32, 0xbf, 0x88, 0x6d, 0xa4, 0x8f, 0xba, 0xf9, 0x89, 0xa2, 0x11, 0x71, 0x87, 0xca, +0xfb, 0x1f, 0xb5, 0x80, 0x31, 0x76, 0x90, 0xe3, 0xcc, 0xd4, 0x46, 0x92, 0x0b, 0x7a, 0xf8, 0x2b, +0x31, 0xdb, 0x58, 0x04, 0xd8, 0x7d, 0x01, 0x51, 0x4a, 0xcb, 0xfa, 0x91, 0x56, 0xe7, 0x82, 0xf8, +0x67, 0xf6, 0xbe, 0xd9, 0x44, 0x9e, 0x0e, 0x9a, 0x2c, 0x09, 0xbc, 0xec, 0xc6, 0xaa, 0x08, 0x76, +0x36, 0x96, 0x5e, 0x34, 0xb3, 0xec, 0x76, 0x6f, 0x2f, 0xe2, 0xe4, 0x30, 0x18, 0xa2, 0xfd, 0xde, +0xb1, 0x40, 0x61, 0x6a, 0x0e, 0x9d, 0x82, 0xe5, 0x33, 0x10, 0x24, 0xee, 0x06, 0x52, 0xfc, 0x76, +0x41 +}; + +/**********************************************************************************************/ +#if 1 +/* RSA modulus n: */ +const uint8_t modulus2[] PROGMEM = { +0x01, 0x94, 0x7c, 0x7f, 0xce, 0x90, 0x42, 0x5f, 0x47, 0x27, 0x9e, 0x70, 0x85, 0x1f, 0x25, 0xd5, +0xe6, 0x23, 0x16, 0xfe, 0x8a, 0x1d, 0xf1, 0x93, 0x71, 0xe3, 0xe6, 0x28, 0xe2, 0x60, 0x54, 0x3e, +0x49, 0x01, 0xef, 0x60, 0x81, 0xf6, 0x8c, 0x0b, 0x81, 0x41, 0x19, 0x0d, 0x2a, 0xe8, 0xda, 0xba, +0x7d, 0x12, 0x50, 0xec, 0x6d, 0xb6, 0x36, 0xe9, 0x44, 0xec, 0x37, 0x22, 0x87, 0x7c, 0x7c, 0x1d, +0x0a, 0x67, 0xf1, 0x4b, 0x16, 0x94, 0xc5, 0xf0, 0x37, 0x94, 0x51, 0xa4, 0x3e, 0x49, 0xa3, 0x2d, +0xde, 0x83, 0x67, 0x0b, 0x73, 0xda, 0x91, 0xa1, 0xc9, 0x9b, 0xc2, 0x3b, 0x43, 0x6a, 0x60, 0x05, +0x5c, 0x61, 0x0f, 0x0b, 0xaf, 0x99, 0xc1, 0xa0, 0x79, 0x56, 0x5b, 0x95, 0xa3, 0xf1, 0x52, 0x66, +0x32, 0xd1, 0xd4, 0xda, 0x60, 0xf2, 0x0e, 0xda, 0x25, 0xe6, 0x53, 0xc4, 0xf0, 0x02, 0x76, 0x6f, +0x45 +}; + +/* RSA public exponent e: */ +const uint8_t public_exponent2[] PROGMEM = { +0x01, 0x00, 0x01 +}; + +/* RSA private exponent d: */ +const uint8_t private_exponent2[] PROGMEM = { +0x08, 0x23, 0xf2, 0x0f, 0xad, 0xb5, 0xda, 0x89, 0x08, 0x8a, 0x9d, 0x00, 0x89, 0x3e, 0x21, 0xfa, +0x4a, 0x1b, 0x11, 0xfb, 0xc9, 0x3c, 0x64, 0xa3, 0xbe, 0x0b, 0xaa, 0xea, 0x97, 0xfb, 0x3b, 0x93, +0xc3, 0xff, 0x71, 0x37, 0x04, 0xc1, 0x9c, 0x96, 0x3c, 0x1d, 0x10, 0x7a, 0xae, 0x99, 0x05, 0x47, +0x39, 0xf7, 0x9e, 0x02, 0xe1, 0x86, 0xde, 0x86, 0xf8, 0x7a, 0x6d, 0xde, 0xfe, 0xa6, 0xd8, 0xcc, +0xd1, 0xd3, 0xc8, 0x1a, 0x47, 0xbf, 0xa7, 0x25, 0x5b, 0xe2, 0x06, 0x01, 0xa4, 0xa4, 0xb2, 0xf0, +0x8a, 0x16, 0x7b, 0x5e, 0x27, 0x9d, 0x71, 0x5b, 0x1b, 0x45, 0x5b, 0xdd, 0x7e, 0xab, 0x24, 0x59, +0x41, 0xd9, 0x76, 0x8b, 0x9a, 0xce, 0xfb, 0x3c, 0xcd, 0xa5, 0x95, 0x2d, 0xa3, 0xce, 0xe7, 0x25, +0x25, 0xb4, 0x50, 0x16, 0x63, 0xa8, 0xee, 0x15, 0xc9, 0xe9, 0x92, 0xd9, 0x24, 0x62, 0xfe, 0x39 +}; + +/* Prime p: */ +const uint8_t p2[] PROGMEM = { +0x01, 0x59, 0xdb, 0xde, 0x04, 0xa3, 0x3e, 0xf0, 0x6f, 0xb6, 0x08, 0xb8, 0x0b, 0x19, 0x0f, 0x4d, +0x3e, 0x22, 0xbc, 0xc1, 0x3a, 0xc8, 0xe4, 0xa0, 0x81, 0x03, 0x3a, 0xbf, 0xa4, 0x16, 0xed, 0xb0, +0xb3, 0x38, 0xaa, 0x08, 0xb5, 0x73, 0x09, 0xea, 0x5a, 0x52, 0x40, 0xe7, 0xdc, 0x6e, 0x54, 0x37, +0x8c, 0x69, 0x41, 0x4c, 0x31, 0xd9, 0x7d, 0xdb, 0x1f, 0x40, 0x6d, 0xb3, 0x76, 0x9c, 0xc4, 0x1a, +0x43 +}; + +/* Prime q: */ +const uint8_t q2[] PROGMEM = { +0x01, 0x2b, 0x65, 0x2f, 0x30, 0x40, 0x3b, 0x38, 0xb4, 0x09, 0x95, 0xfd, 0x6f, 0xf4, 0x1a, 0x1a, +0xcc, 0x8a, 0xda, 0x70, 0x37, 0x32, 0x36, 0xb7, 0x20, 0x2d, 0x39, 0xb2, 0xee, 0x30, 0xcf, 0xb4, +0x6d, 0xb0, 0x95, 0x11, 0xf6, 0xf3, 0x07, 0xcc, 0x61, 0xcc, 0x21, 0x60, 0x6c, 0x18, 0xa7, 0x5b, +0x8a, 0x62, 0xf8, 0x22, 0xdf, 0x03, 0x1b, 0xa0, 0xdf, 0x0d, 0xaf, 0xd5, 0x50, 0x6f, 0x56, 0x8b, +0xd7 +}; + +/* p's CRT exponent dP: */ +const uint8_t dp2[] PROGMEM = { +0x43, 0x6e, 0xf5, 0x08, 0xde, 0x73, 0x65, 0x19, 0xc2, 0xda, 0x4c, 0x58, 0x0d, 0x98, 0xc8, 0x2c, +0xb7, 0x45, 0x2a, 0x3f, 0xb5, 0xef, 0xad, 0xc3, 0xb9, 0xc7, 0x78, 0x9a, 0x1b, 0xc6, 0x58, 0x4f, +0x79, 0x5a, 0xdd, 0xbb, 0xd3, 0x24, 0x39, 0xc7, 0x46, 0x86, 0x55, 0x2e, 0xcb, 0x6c, 0x2c, 0x30, +0x7a, 0x4d, 0x3a, 0xf7, 0xf5, 0x39, 0xee, 0xc1, 0x57, 0x24, 0x8c, 0x7b, 0x31, 0xf1, 0xa2, 0x55 +}; + +/* q's CRT exponent dQ: */ +const uint8_t dq2[] PROGMEM = { +0x01, 0x2b, 0x15, 0xa8, 0x9f, 0x3d, 0xfb, 0x2b, 0x39, 0x07, 0x3e, 0x73, 0xf0, 0x2b, 0xdd, 0x0c, +0x1a, 0x7b, 0x37, 0x9d, 0xd4, 0x35, 0xf0, 0x5c, 0xdd, 0xe2, 0xef, 0xf9, 0xe4, 0x62, 0x94, 0x8b, +0x7c, 0xec, 0x62, 0xee, 0x90, 0x50, 0xd5, 0xe0, 0x81, 0x6e, 0x07, 0x85, 0xa8, 0x56, 0xb4, 0x91, +0x08, 0xdc, 0xb7, 0x5f, 0x36, 0x83, 0x87, 0x4d, 0x1c, 0xa6, 0x32, 0x9a, 0x19, 0x01, 0x30, 0x66, +0xff +}; + +/* CRT coefficient qInv: */ +const uint8_t qinv2[] PROGMEM = { +0x02, 0x70, 0xdb, 0x17, 0xd5, 0x91, 0x4b, 0x01, 0x8d, 0x76, 0x11, 0x8b, 0x24, 0x38, 0x9a, 0x73, +0x50, 0xec, 0x83, 0x6b, 0x00, 0x63, 0xa2, 0x17, 0x21, 0x23, 0x6f, 0xd8, 0xed, 0xb6, 0xd8, 0x9b, +0x51, 0xe7, 0xee, 0xb8, 0x7b, 0x61, 0x1b, 0x71, 0x32, 0xcb, 0x7e, 0xa7, 0x35, 0x6c, 0x23, 0x15, +0x1c, 0x1e, 0x77, 0x51, 0x50, 0x7c, 0x78, 0x6d, 0x9e, 0xe1, 0x79, 0x41, 0x70, 0xa8, 0xc8, 0xe8 +}; + +#endif +/**********************************************************************************************/ + + +uint8_t keys_allocated = 0; +rsa_publickey_t pub_key; +rsa_privatekey_t priv_key; + +#if 0 + #define MSG message + #define SEED seed + #define ENCRYPTED encrypted + #define MODULUS modulus + #define PUB_EXPONENT public_exponent + #define PRIV_EXPONENT private_exponent + #define P p + #define Q q + #define DP dp + #define DQ dq + #define QINV qinv +#else + #define MSG message4 + #define SEED seed4 + #define ENCRYPTED encrypted4 + #define MODULUS modulus2 + #define PUB_EXPONENT public_exponent2 + #define PRIV_EXPONENT private_exponent2 + #define P p2 + #define Q q2 + #define DP dp2 + #define DQ dq2 + #define QINV qinv2 +#endif + + +uint8_t convert_nibble(uint8_t c){ + if(c>='0' && c<='9'){ + return c - '0'; + } + c |= 'A' ^ 'a'; + if(c>='a' && c<='f'){ + return c - 'a' + 10; + } + return 0xff; +} + +const char *block_ignore_string=" \t\r\n,;"; +#define BUFFER_LIMIT 120 +uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){ + uint16_t counter = 0; + uint16_t c; + uint8_t v, tmp = 0, idx = 0; + if(!ignore_string){ + ignore_string = block_ignore_string; + } + while(counter < length){ + c = cli_getc(); + if(c > 0xff){ + return counter; + } + if(strchr(ignore_string, c)){ + continue; + } + v = convert_nibble(c); + if(v > 0x0f){ + return counter; + } + if(idx){ + ((uint8_t*)dst)[counter++] = (tmp << 4) | v; + idx = 0; + if(counter % (BUFFER_LIMIT/2) == 0){ + cli_putc('.'); + } + }else{ + tmp = v; + idx = 1; + } + } + return counter; +} + +uint16_t own_atou(const char* str){ + uint16_t r=0; + while(*str && *str >= '0' && *str <= '9'){ + r *= 10; + r += *str++ - '0'; + } + return r; +} + +uint8_t read_bigint(bigint_t* a, char* prompt){ + uint16_t read_length, actual_length; + uint8_t off; + uint8_t *buffer; + char read_int_str[18]; + cli_putstr(prompt); + cli_putstr_P(PSTR("\r\n length: ")); + cli_getsn(read_int_str, 16); + read_length = own_atou(read_int_str); + off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t); + buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)); + if(!buffer){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + cli_putstr_P(PSTR("\r\n data: ")); + memset(buffer, 0, sizeof(bigint_word_t)); + actual_length = read_os(buffer + off, read_length, NULL); + if(actual_length != read_length){ + cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!")); + free(buffer); + return 1; + } + a->wordv = (bigint_word_t*)buffer; + a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + a->info = 0; + bigint_changeendianess(a); + bigint_adjust(a); + return 0; +} + +uint8_t pre_alloc_key_crt(void){ + uint8_t c; + pub_key.modulus = malloc(sizeof(bigint_t)); + if(!pub_key.modulus){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + priv_key.modulus = pub_key.modulus; + priv_key.n = 5; + priv_key.components = malloc(5 * sizeof(bigint_t*)); + if(!priv_key.components){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + pub_key.exponent = malloc(sizeof(bigint_t)); + if(!pub_key.exponent){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + for(c=0; c<5; ++c){ + priv_key.components[c] = malloc(sizeof(bigint_t)); + if(!priv_key.components[c]){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + } + return 0; +} + +void free_key(void){ + uint8_t c; + free(pub_key.modulus->wordv); + free(pub_key.exponent->wordv); + free(pub_key.modulus); + pub_key.modulus = priv_key.modulus = NULL; + free(pub_key.exponent); + pub_key.exponent = NULL; + for(c = 0; c < priv_key.n; ++c){ + free(priv_key.components[c]->wordv); + free(priv_key.components[c]); + } + free(priv_key.components); + priv_key.components = NULL; +} + +uint8_t read_key_crt(void){ + uint8_t r; + cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); + r = pre_alloc_key_crt(); + if(r) return r; + r = read_bigint(pub_key.modulus,"\r\n = module ="); + if(r) return r; + r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); + if(r) return r; + r = read_bigint(priv_key.components[0],"\r\n = p (first prime) ="); + if(r) return r; + r = read_bigint(priv_key.components[1],"\r\n = q (second prime) ="); + if(r) return r; + r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) ="); + if(r) return r; + r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) ="); + if(r) return r; + r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) ="); + return r; +} + +uint8_t read_key_conv(void){ + uint8_t r; + cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); + pub_key.modulus = malloc(sizeof(bigint_t)); + if(!pub_key.modulus){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + r = read_bigint(pub_key.modulus,"\r\n = module ="); + if(r) return r; + priv_key.modulus = pub_key.modulus; + priv_key.n = 1; + pub_key.exponent = malloc(sizeof(bigint_t)); + if(!pub_key.exponent){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + priv_key.components = malloc(sizeof(bigint_t*)); + if(!priv_key.components){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + priv_key.components[0] = malloc(sizeof(bigint_t)); + if(!priv_key.components[0]){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); + if(r) return r; + r = read_bigint(priv_key.components[0],"\r\n = private exponent ="); + return r; +} + +void load_priv_conventional(void){ + bigint_t *epriv; + epriv = malloc(sizeof(bigint_t)); + if(!epriv){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t)); + if(!epriv->wordv){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT)); + priv_key.components = malloc(sizeof(bigint_t*)); + priv_key.components[0] = epriv; + priv_key.n = 1; + bigint_changeendianess(epriv); + bigint_adjust(epriv); +} + + +void load_priv_crt_mono(void){ + bigint_t **v; + const uint8_t *bv[5] = {P,Q,DP,DQ,QINV}; + uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)}; + uint8_t i; + v = malloc(5 * sizeof(bigint_t)); + if(!v){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + priv_key.components = malloc(5*sizeof(bigint_t*)); + if(!priv_key.components){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + priv_key.n = 5; + for(i=0; i<5; ++i){ + v[i] = malloc(sizeof(bigint_t)); + v[i]->info = 0; + v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t)); + if(!v[i]->wordv){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + memcpy(v[i]->wordv, bv[i], sv[i]); + bigint_changeendianess(v[i]); + bigint_adjust(v[i]); + priv_key.components[i] = v[i]; + } +} + +uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){ + a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t); + a->wordv = malloc(BIGINT_CEIL(length_B)); + if(!a->wordv){ + cli_putstr_P(PSTR("\r\nOOM!\r\n")); + return 1; + } + memset(a->wordv, 0, sizeof(bigint_word_t)); + memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B); + a->info = 0; + bigint_changeendianess(a); + bigint_adjust(a); + return 0; +} + +void load_fix_rsa(void){ + if(keys_allocated){ + free_key(); + } + keys_allocated = 1; + + if(pre_alloc_key_crt()){ + cli_putstr_P(PSTR("\r\nOOM!\r\n")); + return; + } + + load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS)); + load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT)); + priv_key.n = 5; + load_bigint_from_os(priv_key.components[0], P, sizeof(P)); + load_bigint_from_os(priv_key.components[1], Q, sizeof(Q)); + load_bigint_from_os(priv_key.components[2], DP, sizeof(DP)); + load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ)); + load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV)); + +// load_priv_conventional(); +// load_priv_crt_mono(); +} + +void quick_test(void){ + uint8_t *ciphertext, *plaintext, rc; + uint8_t seed[sizeof(SEED)]; + uint16_t clen, plen; + ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t)); + plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t)); + memcpy_P(plaintext, MSG, sizeof(MSG)); + memcpy_P(seed, SEED, sizeof(SEED)); + cli_putstr_P(PSTR("\r\nplaintext:")); + cli_hexdump_block(plaintext, sizeof(MSG), 4, 8); + cli_putstr_P(PSTR("\r\nencrypting: ...")); + rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed); + if(rc){ + cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: ")); + cli_hexdump_byte(rc); + return; + + } + + cli_putstr_P(PSTR("\r\n\r\nciphertext:")); + cli_hexdump_block(ciphertext, clen, 4, 8); + if(clen!=sizeof(ENCRYPTED)){ + cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<")); + }else{ + if(memcmp_P(ciphertext, ENCRYPTED, clen)){ + cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<")); + }else{ + cli_putstr_P(PSTR("\r\n>>OK<<")); + } + } + + cli_putstr_P(PSTR("\r\ndecrypting: ...")); + rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL); + if(rc){ + cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: ")); + cli_hexdump_byte(rc); + return; + } + cli_putstr_P(PSTR("\r\n\r\nplaintext:")); + cli_hexdump_block(plaintext, plen, 4, 8); + + free(ciphertext); + free(plaintext); +} + +void run_seed_test(void){ + uint8_t *msg, *ciph, *msg_; + uint16_t msg_len, ciph_len, msg_len_; + uint8_t seed[20], seed_out[20]; + char read_int_str[18]; + cli_putstr_P(PSTR("\r\n== test with given seed ==")); + cli_putstr_P(PSTR("\r\n = message =")); + cli_putstr_P(PSTR("\r\n length: ")); + cli_getsn(read_int_str, 16); + msg_len = own_atou(read_int_str); + msg = malloc(msg_len); + if(!msg){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + ciph = malloc(bigint_length_B(pub_key.modulus)); + if(!ciph){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + msg_ = malloc(bigint_length_B(pub_key.modulus) + sizeof(bigint_word_t)); + if(!msg_){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + cli_putstr_P(PSTR("\r\n data: ")); + read_os(msg, msg_len, NULL); + cli_putstr_P(PSTR("\r\n seed (20 bytes): ")); + read_os(seed, 20, NULL); + + cli_putstr_P(PSTR("\r\n encrypting ...")); + rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed); + cli_putstr_P(PSTR("\r\n ciphertext:")); + cli_hexdump_block(ciph, ciph_len, 4, 16); + cli_putstr_P(PSTR("\r\n decrypting ... ")); + rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out); + cli_putstr_P(PSTR("[done]")); + if(msg_len != msg_len_){ + char tstr[16]; + cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length (")); + itoa(msg_len_, tstr, 10); + cli_putstr(tstr); + cli_putstr_P(PSTR(" instead of ")); + itoa(msg_len, tstr, 10); + cli_putstr(tstr); + cli_putc(')'); + goto end; + } + if(memcmp(msg, msg_, msg_len)){ + cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:")); + cli_hexdump_block(msg_, msg_len_, 4, 16); + cli_putstr_P(PSTR("\r\nreference:")); + cli_hexdump_block(msg, msg_len, 4, 16); + goto end; + } + + if(memcmp(seed, seed_out, 20)){ + cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:")); + cli_hexdump_block(seed_out, 20, 4, 16); + cli_putstr_P(PSTR("\r\nreference:")); + cli_hexdump_block(seed, 20, 4, 16); + goto end; + } + cli_putstr_P(PSTR("\r\n >>OK<<")); +end: + free(msg); + free(msg_); + free(ciph); +} + +void reset_prng(void){ + uint8_t buf[16]; + memset(buf, 0, 16); + random_seed(buf); + cli_putstr_P(PSTR("\r\nPRNG reset")); +} + +void rsa_init(void){ + prng_get_byte = random8; +} + +void load_key(void){ + if(keys_allocated){ + free_key(); + } + keys_allocated = 1; + read_key_crt(); +} + +void test_dump(void){ + char lstr[16]; + int len; + cli_putstr_P(PSTR("\r\nenter dump length: ")); + cli_getsn_cecho(lstr, 15); + len = own_atou(lstr); + cli_putstr_P(PSTR("\r\ndumping 0x")); + cli_hexdump_rev(&len, 2); + cli_putstr_P(PSTR(" byte:")); + cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8); +} + +/***************************************************************************** + * main * + *****************************************************************************/ + +const char echo_test_str[] PROGMEM = "echo-test"; +const char reset_prng_str[] PROGMEM = "reset-prng"; +const char load_key_str[] PROGMEM = "load-key"; +const char load_fix_key_str[] PROGMEM = "load-fix-key"; +const char quick_test_str[] PROGMEM = "quick-test"; +const char seed_test_str[] PROGMEM = "seed-test"; +const char dump_test_str[] PROGMEM = "dump-test"; +const char performance_str[] PROGMEM = "performance"; +const char echo_str[] PROGMEM = "echo"; + +const cmdlist_entry_t cmdlist[] PROGMEM = { + { reset_prng_str, NULL, reset_prng }, + { load_key_str, NULL, load_key }, + { load_fix_key_str, NULL, load_fix_rsa }, + { quick_test_str, NULL, quick_test }, + { seed_test_str, NULL, run_seed_test }, + { dump_test_str, NULL, test_dump }, +// { performance_str, NULL, testrun_performance_bigint }, + { echo_str, (void*)1, (void_fpt)echo_ctrl }, + { NULL, NULL, NULL } +}; + +void dump_sp(void){ + uint8_t x; + uint8_t *xa = &x; + cli_putstr_P(PSTR("\r\nstack pointer: ~")); + cli_hexdump_rev(&xa, 4); +} + +int main (void){ + main_setup(); + + for(;;){ + welcome_msg(algo_name); + rsa_init(); + cmd_interface(cmdlist); + } +} diff --git a/test_src/main-rsaes_pkcs1v15-test.c b/test_src/main-rsaes_pkcs1v15-test.c new file mode 100644 index 0000000..efea72c --- /dev/null +++ b/test_src/main-rsaes_pkcs1v15-test.c @@ -0,0 +1,718 @@ +/* main-dsa-test.c */ +/* + This file is part of the ARM-Crypto-Lib. + Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + * RSA test-suit + * +*/ +#include "main-test-common.h" + +#include "noekeon.h" +#include "noekeon_prng.h" +#include "bigint.h" +#include "bigint_io.h" +#include "random_dummy.h" +#include "rsa_basic.h" +#include "rsaes_pkcs1v15.h" + +#include "performance_test.h" + +#define DEBUG 0 + +const char* algo_name = "RSAES-PKCS1V15"; + +#define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)) +#define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t)) + +/***************************************************************************** + * additional validation-functions * + *****************************************************************************/ + +/* Modulus: */ +const uint8_t modulus[] PROGMEM = { +0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4, +0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab, +0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85, +0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72, +0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97, +0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14, +0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24, +0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb +}; + +/* Public exponent: */ +const uint8_t pub_exponent[] PROGMEM = { 0x01, 0x00, 0x01 }; + +/* Exponent: */ +const uint8_t priv_exponent[] PROGMEM = { +0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c, +0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd, +0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b, +0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55, +0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73, +0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf, +0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde, +0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1 +}; + +/* Prime 1: */ +const uint8_t p[] PROGMEM = { +0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b, +0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a, +0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1, +0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d +}; + +/* Prime 2: */ +const uint8_t q[] PROGMEM = { +0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7, +0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c, +0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe, +0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77 +}; + +/* Prime exponent 1: */ +const uint8_t dp[] PROGMEM = { +0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04, +0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3, +0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d, +0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1 +}; + +/* Prime exponent 2: */ +const uint8_t dq[] PROGMEM = { +0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc, +0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73, +0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a, +0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83 +}; + +/* Coefficient: */ +const uint8_t qinv[] PROGMEM = { +0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d, +0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11, +0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81, +0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1 +}; + +/* PKCS#1 v1.5 encryption of 0x20, random messages with random s0xee,ds + * --------------------------------------------------------------------------- + */ + +/* Message: */ +const uint8_t message_x[] PROGMEM = { +0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23, +0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34 +}; + +/* Seed: */ +const uint8_t seed_x[] PROGMEM = { +0x01, 0x73, 0x41, 0xae, 0x38, 0x75, 0xd5, 0xf8, 0x71, 0x01, 0xf8, 0xcc, 0x4f, 0xa9, 0xb9, 0xbc, +0x15, 0x6b, 0xb0, 0x46, 0x28, 0xfc, 0xcd, 0xb2, 0xf4, 0xf1, 0x1e, 0x90, 0x5b, 0xd3, 0xa1, 0x55, +0xd3, 0x76, 0xf5, 0x93, 0xbd, 0x73, 0x04, 0x21, 0x08, 0x74, 0xeb, 0xa0, 0x8a, 0x5e, 0x22, 0xbc, +0xcc, 0xb4, 0xc9, 0xd3, 0x88, 0x2a, 0x93, 0xa5, 0x4d, 0xb0, 0x22, 0xf5, 0x03, 0xd1, 0x63, 0x38, +0xb6, 0xb7, 0xce, 0x16, 0xdc, 0x7f, 0x4b, 0xbf, 0x9a, 0x96, 0xb5, 0x97, 0x72, 0xd6, 0x60, 0x6e, +0x97, 0x47, 0xc7, 0x64, 0x9b, 0xf9, 0xe0, 0x83, 0xdb, 0x98, 0x18, 0x84, 0xa9, 0x54, 0xab, 0x3c, +0x6f }; + +/* Encryption: */ +const uint8_t encrypted_x[] PROGMEM = { +0x50, 0xb4, 0xc1, 0x41, 0x36, 0xbd, 0x19, 0x8c, 0x2f, 0x3c, 0x3e, 0xd2, 0x43, 0xfc, 0xe0, 0x36, +0xe1, 0x68, 0xd5, 0x65, 0x17, 0x98, 0x4a, 0x26, 0x3c, 0xd6, 0x64, 0x92, 0xb8, 0x08, 0x04, 0xf1, +0x69, 0xd2, 0x10, 0xf2, 0xb9, 0xbd, 0xfb, 0x48, 0xb1, 0x2f, 0x9e, 0xa0, 0x50, 0x09, 0xc7, 0x7d, +0xa2, 0x57, 0xcc, 0x60, 0x0c, 0xce, 0xfe, 0x3a, 0x62, 0x83, 0x78, 0x9d, 0x8e, 0xa0, 0xe6, 0x07, +0xac, 0x58, 0xe2, 0x69, 0x0e, 0xc4, 0xeb, 0xc1, 0x01, 0x46, 0xe8, 0xcb, 0xaa, 0x5e, 0xd4, 0xd5, +0xcc, 0xe6, 0xfe, 0x7b, 0x0f, 0xf9, 0xef, 0xc1, 0xea, 0xbb, 0x56, 0x4d, 0xbf, 0x49, 0x82, 0x85, +0xf4, 0x49, 0xee, 0x61, 0xdd, 0x7b, 0x42, 0xee, 0x5b, 0x58, 0x92, 0xcb, 0x90, 0x60, 0x1f, 0x30, +0xcd, 0xa0, 0x7b, 0xf2, 0x64, 0x89, 0x31, 0x0b, 0xcd, 0x23, 0xb5, 0x28, 0xce, 0xab, 0x3c, 0x31 +}; + +uint8_t keys_allocated = 0; +rsa_publickey_t pub_key; +rsa_privatekey_t priv_key; + +#if 1 + #define MSG message_x + #define SEED seed_x + #define ENCRYPTED encrypted_x + #define MODULUS modulus + #define PUB_EXPONENT pub_exponent + #define PRIV_EXPONENT priv_exponent + #define P p + #define Q q + #define DP dp + #define DQ dq + #define QINV qinv +#endif + + +uint8_t convert_nibble(uint8_t c){ + if(c>='0' && c<='9'){ + return c - '0'; + } + c |= 'A' ^ 'a'; + if(c>='a' && c<='f'){ + return c - 'a' + 10; + } + return 0xff; +} + +const char *block_ignore_string=" \t\r\n,;"; +#define BUFFER_LIMIT 120 +uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){ + uint16_t counter = 0; + uint16_t c; + uint8_t v, tmp = 0, idx = 0; + if(!ignore_string){ + ignore_string = block_ignore_string; + } + while(counter < length){ + c = cli_getc(); + if(c > 0xff){ + return counter; + } + if(strchr(ignore_string, c)){ + continue; + } + v = convert_nibble(c); + if(v > 0x0f){ + return counter; + } + if(idx){ + ((uint8_t*)dst)[counter++] = (tmp << 4) | v; + idx = 0; + if(counter % (BUFFER_LIMIT/2) == 0){ + cli_putc('.'); + } + }else{ + tmp = v; + idx = 1; + } + } + return counter; +} + +uint16_t own_atou(const char* str){ + uint16_t r=0; + while(*str && *str >= '0' && *str <= '9'){ + r *= 10; + r += *str++ - '0'; + } + return r; +} + +uint8_t read_bigint(bigint_t* a, char* prompt){ + uint16_t read_length, actual_length; + uint8_t off; + uint8_t *buffer; + char read_int_str[18]; + cli_putstr(prompt); + cli_putstr_P(PSTR("\r\n length: ")); + cli_getsn(read_int_str, 16); + read_length = own_atou(read_int_str); + off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t); + buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t)); + if(!buffer){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + cli_putstr_P(PSTR("\r\n data: ")); + memset(buffer, 0, sizeof(bigint_word_t)); + actual_length = read_os(buffer + off, read_length, NULL); + if(actual_length != read_length){ + cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!")); + free(buffer); + return 1; + } + a->wordv = (bigint_word_t*)buffer; + a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + a->info = 0; + bigint_changeendianess(a); + bigint_adjust(a); + return 0; +} + +uint8_t pre_alloc_key_crt(void){ + uint8_t c; + pub_key.modulus = malloc(sizeof(bigint_t)); + if(!pub_key.modulus){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 6; + } + priv_key.modulus = pub_key.modulus; + priv_key.n = 5; + priv_key.components = malloc(5 * sizeof(bigint_t*)); + if(!priv_key.components){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 3; + } + pub_key.exponent = malloc(sizeof(bigint_t)); + if(!pub_key.exponent){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 4; + } + for(c=0; c<5; ++c){ + priv_key.components[c] = malloc(sizeof(bigint_t)); + if(!priv_key.components[c]){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 7+c; + } + } + return 0; +} + +void free_key(void){ + uint8_t c; + for(c = priv_key.n; c > 0 ; --c){ + free(priv_key.components[c - 1]->wordv); + } + free(pub_key.exponent->wordv); + free(pub_key.modulus->wordv); + + for(c = priv_key.n; c > 0 ; --c){ + free(priv_key.components[c - 1]); + } + free(pub_key.exponent); + pub_key.exponent = NULL; + free(priv_key.components); + priv_key.components = NULL; + free(pub_key.modulus); + pub_key.modulus = priv_key.modulus = NULL; + keys_allocated = 0; +} + +uint8_t read_key_crt(void){ + uint8_t r; + cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); + r = pre_alloc_key_crt(); + if(r) return r; + r = read_bigint(pub_key.modulus,"\r\n = module ="); + if(r) return r; + r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); + if(r) return r; + r = read_bigint(priv_key.components[0],"\r\n = p (first prime) ="); + if(r) return r; + r = read_bigint(priv_key.components[1],"\r\n = q (second prime) ="); + if(r) return r; + r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) ="); + if(r) return r; + r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) ="); + if(r) return r; + r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) ="); + +#if DEBUG + cli_putstr_P(PSTR("\r\nmodulus:")); + bigint_print_hex(pub_key.modulus); + cli_putstr_P(PSTR("\r\npublic exponent:")); + bigint_print_hex(pub_key.exponent); + cli_putstr_P(PSTR("\r\np:")); + bigint_print_hex(priv_key.components[0]); + cli_putstr_P(PSTR("\r\nq:")); + bigint_print_hex(priv_key.components[1]); + cli_putstr_P(PSTR("\r\ndP:")); + bigint_print_hex(priv_key.components[2]); + cli_putstr_P(PSTR("\r\ndQ:")); + bigint_print_hex(priv_key.components[3]); + cli_putstr_P(PSTR("\r\nqInv:")); + bigint_print_hex(priv_key.components[4]); +#endif + return r; +} + +uint8_t read_key_conv(void){ + uint8_t r; + cli_putstr_P(PSTR("\r\n== reading key (crt) ==")); + pub_key.modulus = malloc(sizeof(bigint_t)); + if(!pub_key.modulus){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + r = read_bigint(pub_key.modulus,"\r\n = module ="); + if(r) return r; + priv_key.modulus = pub_key.modulus; + priv_key.n = 1; + pub_key.exponent = malloc(sizeof(bigint_t)); + if(!pub_key.exponent){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + priv_key.components = malloc(sizeof(bigint_t*)); + if(!priv_key.components){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + priv_key.components[0] = malloc(sizeof(bigint_t)); + if(!priv_key.components[0]){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return 2; + } + r = read_bigint(pub_key.exponent,"\r\n = public exponent ="); + if(r) return r; + r = read_bigint(priv_key.components[0],"\r\n = private exponent ="); + return r; +} + +void load_priv_conventional(void){ + bigint_t *epriv; + epriv = malloc(sizeof(bigint_t)); + if(!epriv){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t)); + if(!epriv->wordv){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT)); + priv_key.components = malloc(sizeof(bigint_t*)); + priv_key.components[0] = epriv; + priv_key.n = 1; + bigint_changeendianess(epriv); + bigint_adjust(epriv); +} + + +void load_priv_crt_mono(void){ + bigint_t **v; + const uint8_t *bv[5] = {P,Q,DP,DQ,QINV}; + uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)}; + uint8_t i; + v = malloc(5 * sizeof(bigint_t)); + if(!v){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + priv_key.components = malloc(5*sizeof(bigint_t*)); + if(!priv_key.components){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + priv_key.n = 5; + for(i=0; i<5; ++i){ + v[i] = malloc(sizeof(bigint_t)); + v[i]->info = 0; + v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t)); + if(!v[i]->wordv){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + memcpy(v[i]->wordv, bv[i], sv[i]); + bigint_changeendianess(v[i]); + bigint_adjust(v[i]); + priv_key.components[i] = v[i]; + } +} + +uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){ + a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t); + a->wordv = malloc(BIGINT_CEIL(length_B)); + if(!a->wordv){ + cli_putstr_P(PSTR("\r\nOOM!\r\n")); + return 1; + } + memset(a->wordv, 0, sizeof(bigint_word_t)); + memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B); + a->info = 0; + bigint_changeendianess(a); + bigint_adjust(a); + return 0; +} + +void load_fix_rsa(void){ + if(keys_allocated){ + free_key(); + } + keys_allocated = 1; + + if(pre_alloc_key_crt()){ + cli_putstr_P(PSTR("\r\nOOM!\r\n")); + return; + } + + load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS)); + load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT)); + priv_key.n = 5; + load_bigint_from_os(priv_key.components[0], P, sizeof(P)); + load_bigint_from_os(priv_key.components[1], Q, sizeof(Q)); + load_bigint_from_os(priv_key.components[2], DP, sizeof(DP)); + load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ)); + load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV)); + +// load_priv_conventional(); +// load_priv_crt_mono(); +} + +void quick_test(void){ + uint8_t *ciphertext, *plaintext, rc; + uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)]; + uint16_t clen, plen; + if(!keys_allocated){ + load_fix_rsa(); + } + ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t)); + plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t)); + memcpy_P(plaintext, MSG, sizeof(MSG)); + memcpy_P(seed, SEED, sizeof(SEED)); + cli_putstr_P(PSTR("\r\nplaintext:")); + cli_hexdump_block(plaintext, sizeof(MSG), 4, 16); + cli_putstr_P(PSTR("\r\nseed:")); + cli_hexdump_block(seed, sizeof(SEED), 4, 16); + cli_putstr_P(PSTR("\r\nencrypting: ...")); + + rc = rsa_encrypt_pkcs1v15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed); + if(rc){ + cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_pkcs1v15 returned: ")); + cli_hexdump_byte(rc); + return; + + } + + cli_putstr_P(PSTR("\r\n\r\nciphertext:")); + cli_hexdump_block(ciphertext, clen, 4, 16); + if(clen!=sizeof(ENCRYPTED)){ + cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<")); + }else{ + if(memcmp_P(ciphertext, ENCRYPTED, clen)){ + cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<")); + }else{ + cli_putstr_P(PSTR("\r\n>>OK<<")); + } + } + + cli_putstr_P(PSTR("\r\ndecrypting: ...")); + rc = rsa_decrypt_pkcs1v15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out); + if(rc){ + cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs1v15 returned: ")); + cli_hexdump_byte(rc); + return; + } + cli_putstr_P(PSTR("\r\n\r\nplaintext:")); + cli_hexdump_block(plaintext, plen, 4, 16); + cli_putstr_P(PSTR("\r\n\r\nseed (out):")); + cli_hexdump_block(seed_out, sizeof(SEED), 4, 16); + + free(ciphertext); + free(plaintext); +} + +void run_seed_test(void){ + uint8_t *msg, *ciph, *msg_; + uint16_t ciph_len, msg_len; + uint16_t msg_len_; + uint16_t seed_len; + uint8_t *seed, *seed_out; + char read_int_str[18]; + cli_putstr_P(PSTR("\r\n== test with given seed ==")); + cli_putstr_P(PSTR("\r\n = message =")); + cli_putstr_P(PSTR("\r\n length: ")); + cli_getsn(read_int_str, 16); + msg_len = own_atou(read_int_str); + seed_len = rsa_pkcs1v15_compute_padlength_B(pub_key.modulus, msg_len); + seed = malloc(seed_len); +#if DEBUG + cli_putstr_P(PSTR("\r\nDBG: @seed: 0x")); + cli_hexdump_rev(&seed, 2); +#endif + if(!seed){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + seed_out = malloc(seed_len); +#if DEBUG + cli_putstr_P(PSTR("\r\nDBG: @seed_out: 0x")); + cli_hexdump_rev(&seed_out, 2); +#endif + if(!seed_out){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + msg = malloc(msg_len); +#if DEBUG + cli_putstr_P(PSTR("\r\nDBG: @msg: 0x")); + cli_hexdump_rev(&msg, 2); +#endif + if(!msg){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + ciph = malloc(bigint_length_B(pub_key.modulus)); +#if DEBUG + cli_putstr_P(PSTR("\r\nDBG: @ciph: 0x")); + cli_hexdump_rev(&ciph, 2); +#endif + if(!ciph){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + msg_ = malloc(bigint_length_B(pub_key.modulus) + sizeof(bigint_word_t)); +#if DEBUG + cli_putstr_P(PSTR("\r\nDBG: @msg_: 0x")); + cli_hexdump_rev(&msg_, 2); +#endif + if(!msg_){ + cli_putstr_P(PSTR("\r\nERROR: OOM!")); + return; + } + cli_putstr_P(PSTR("\r\n data: ")); + read_os(msg, msg_len, NULL); + cli_putstr_P(PSTR("\r\n seed (0x")); + cli_hexdump_rev(&seed_len, 2); + cli_putstr_P(PSTR(" bytes): ")); + read_os(seed, seed_len, NULL); + + cli_putstr_P(PSTR("\r\n encrypting ...")); +/* + cli_putstr_P(PSTR("\r\n plaintext:")); + cli_hexdump_block(msg, msg_len, 4, 16); + cli_putstr_P(PSTR("\r\n seed:")); + cli_hexdump_block(seed, seed_len, 4, 16); +*/ +#if DEBUG + cli_putstr_P(PSTR("\r\n first prime:")); + bigint_print_hex(priv_key.components[0]); +#endif + rsa_encrypt_pkcs1v15(ciph, &ciph_len, msg, msg_len, &pub_key, seed); + cli_putstr_P(PSTR("\r\n ciphertext:")); + cli_hexdump_block(ciph, ciph_len, 4, 16); +#if DEBUG + cli_putstr_P(PSTR("\r\n first prime:")); + bigint_print_hex(priv_key.components[0]); +#endif + cli_putstr_P(PSTR("\r\n decrypting ... ")); + + rsa_decrypt_pkcs1v15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out); + + cli_putstr_P(PSTR("[done]")); + if(msg_len != msg_len_){ + char tstr[16]; + cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length (")); + itoa(msg_len_, tstr, 10); + cli_putstr(tstr); + cli_putstr_P(PSTR(" instead of ")); + itoa(msg_len, tstr, 10); + cli_putstr(tstr); + cli_putc(')'); + goto end; + } + if(memcmp(msg, msg_, msg_len)){ + cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:")); + cli_hexdump_block(msg_, msg_len_, 4, 16); + cli_putstr_P(PSTR("\r\nreference:")); + cli_hexdump_block(msg, msg_len, 4, 16); + goto end; + } + + if(memcmp(seed, seed_out, seed_len)){ + cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:")); + cli_hexdump_block(seed_out, seed_len, 4, 16); + cli_putstr_P(PSTR("\r\nreference:")); + cli_hexdump_block(seed, seed_len, 4, 16); + goto end; + } + + cli_putstr_P(PSTR("\r\n >>OK<<")); +end: + free(msg_); + free(ciph); + free(msg); + free(seed_out); + free(seed); +} + +void reset_prng(void){ + uint8_t buf[16]; + memset(buf, 0, 16); + random_seed(buf); + cli_putstr_P(PSTR("\r\nPRNG reset")); +} + +void rsa_init(void){ + prng_get_byte = random8; +} + +void load_key(void){ + uint8_t r; + if(keys_allocated){ + cli_putstr_P(PSTR("\r\nDBG: freeing old keys")); + free_key(); + } + keys_allocated = 1; + r = read_key_crt(); + if(r){ + cli_putstr_P(PSTR("\r\nERROR: read_key_crt returned 0x")); + cli_hexdump_byte(r); + } +} + +void test_dump(void){ + char lstr[16]; + int len; + cli_putstr_P(PSTR("\r\nenter dump length: ")); + cli_getsn_cecho(lstr, 15); + len = own_atou(lstr); + cli_putstr_P(PSTR("\r\ndumping 0x")); + cli_hexdump_rev(&len, 2); + cli_putstr_P(PSTR(" byte:")); + cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8); +} + +/***************************************************************************** + * main * + *****************************************************************************/ + +const char echo_test_str[] PROGMEM = "echo-test"; +const char reset_prng_str[] PROGMEM = "reset-prng"; +const char load_key_str[] PROGMEM = "load-key"; +const char load_fix_key_str[] PROGMEM = "load-fix-key"; +const char quick_test_str[] PROGMEM = "quick-test"; +const char seed_test_str[] PROGMEM = "seed-test"; +const char dump_test_str[] PROGMEM = "dump-test"; +const char performance_str[] PROGMEM = "performance"; +const char echo_str[] PROGMEM = "echo"; + +const cmdlist_entry_t cmdlist[] PROGMEM = { + { reset_prng_str, NULL, reset_prng }, + { load_key_str, NULL, load_key }, + { load_fix_key_str, NULL, load_fix_rsa }, + { quick_test_str, NULL, quick_test }, + { seed_test_str, NULL, run_seed_test }, + { dump_test_str, NULL, test_dump }, +// { performance_str, NULL, testrun_performance_bigint }, + { echo_str, (void*)1, (void_fpt)echo_ctrl }, + { NULL, NULL, NULL } +}; + +void dump_sp(void){ + uint8_t x; + uint8_t *xa = &x; + cli_putstr_P(PSTR("\r\nstack pointer: ~")); + cli_hexdump_rev(&xa, 4); +} + +int main (void){ + main_setup(); + + for(;;){ + welcome_msg(algo_name); + rsa_init(); + cmd_interface(cmdlist); + } +} diff --git a/test_src/main-salsa20-test.c b/test_src/main-salsa20-test.c index 0332457..9e8bb2f 100644 --- a/test_src/main-salsa20-test.c +++ b/test_src/main-salsa20-test.c @@ -51,10 +51,10 @@ void nessie_first(void){ cli_hexdump(key, 16); salsa20_init(key, 128, NULL, &ctx); cli_putstr_P(PSTR("\r\n internal state: ")); - cli_hexdump_block(ctx.a, 64, 4, 16); + cli_hexdump_block(ctx.a.v8, 64, 4, 16); salsa20_gen(&ctx); cli_putstr_P(PSTR("\r\n internal state: ")); - cli_hexdump_block(ctx.a, 64, 4, 16); + cli_hexdump_block(ctx.a.v8, 64, 4, 16); cli_putstr_P(PSTR("\r\n data: ")); cli_hexdump_block(ctx.buffer, 64, 4, 16); @@ -63,13 +63,13 @@ void nessie_first(void){ key[15] = 0x01; cli_putstr_P(PSTR("\r\n testing with key: ")); cli_hexdump(key, 16); - cli_hexdump_block(ctx.a, 64, 4, 16); + cli_hexdump_block(ctx.a.v8, 64, 4, 16); salsa20_init(key, 128, NULL, &ctx); cli_putstr_P(PSTR("\r\n internal state: ")); - cli_hexdump_block(ctx.a, 64, 4, 16); + cli_hexdump_block(ctx.a.v8, 64, 4, 16); salsa20_gen(&ctx); cli_putstr_P(PSTR("\r\n internal state: ")); - cli_hexdump_block(ctx.a, 64, 4, 16); + cli_hexdump_block(ctx.a.v8, 64, 4, 16); cli_putstr_P(PSTR("\r\n data: ")); cli_hexdump_block(ctx.buffer, 64, 4, 16); } diff --git a/twister/twister-large.c b/twister/twister-large.c index 1775488..36506be 100644 --- a/twister/twister-large.c +++ b/twister/twister-large.c @@ -109,7 +109,11 @@ void twister_large_nextBlock(twister_large_ctx_t* ctx, const void* msg){ /*********************************************************************/ void twister_inject_chksum(twister_large_ctx_t* ctx, uint8_t col){ - *((uint64_t*)(&ctx->state.s[7][0])) ^= *((uint64_t*)(&ctx->checksum[col][0])); + uint8_t i=7; + do{ + ctx->state.s[7][i] ^= ctx->checksum[col][i]; + + }while(i--); twister_blank_round(&ctx->state); } diff --git a/whirlpool/whirlpool.c b/whirlpool/whirlpool.c index e975b28..2565b70 100644 --- a/whirlpool/whirlpool.c +++ b/whirlpool/whirlpool.c @@ -111,7 +111,7 @@ static const uint8_t sbox[256] PROGMEM = { #endif -static void gamma(uint8_t* a){ +static void gamma_1(uint8_t* a){ uint8_t i; for(i=0; i<64; ++i){ *a = whirlpool_sbox(*a); @@ -161,7 +161,7 @@ static void theta(uint8_t* a){ } static void w_round(uint8_t* a, const uint8_t* k){ - gamma(a); + gamma_1(a); #if DEBUG cli_putstr_P(PSTR("\r\n pre-pi:")); cli_hexdump_block(a, 64, 4, 8);