-Поиск по дневнику

Поиск сообщений в rss_thedaily_wtf

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 06.04.2008
Записей:
Комментариев:
Написано: 0


CodeSOD: Elliptical Curveball

Понедельник, 07 Декабря 2015 г. 14:30 + в цитатник

Why is it that you hear people saying, dont roll your own crypto? It cant be that bad, right? I mean, if the code gives the correct outputs when given the correct inputs?

Everything in cryptography depends upon high quality random numbers, and lots of them. People get into semi-informed flamewars about what entropy means, government agencies sneak backdoors into algorithms, performance matters, secrecy matters, and unpredictability matters. The standard which defines four randomness generators is NIST Special Publication 80090. One of the four raised suspicions because it (Dual_EC_DRBG) was three times slower than any of the others.

Joe… well, Joe sends us his own code, which fixed this. He made one of the others slower. Using MySQL stored procedures. Just bear in mind, with the below, that its still cleaner, more comprehensible, and generally saner than OpenSSL.

--
-- prng_nistctr_sp
-- Implements the NIST SP 800-90 CTR_DRBG cryptographic random number generator standard
-- with MySQL AES_ENCRYPT() as the block cipher (256 bit seed, 128 bit output)
--


DELIMITER //

DROP FUNCTION prng.make_128bit_block//
CREATE DEFINER = 'prng'@'localhost'
FUNCTION prng.make_128bit_block (p_h BIGINT UNSIGNED, p_l BIGINT UNSIGNED)
RETURNS TEXT
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 RETURN UNHEX( CONCAT(LPAD(HEX(p_h),16,'0'),LPAD(HEX(p_l),16,'0')) );
END;
//

DROP PROCEDURE prng.inc_128bit_value//
CREATE DEFINER = 'prng'@'localhost'
PROCEDURE prng.inc_128bit_value (INOUT p_h BIGINT UNSIGNED, INOUT p_l BIGINT UNSIGNED)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 IF p_l < 18446744073709551615 THEN
 SET p_l = p_l + 1;
 ELSE
 SET p_l = 0;
 IF p_h < 18446744073709551615 THEN
 SET p_h = p_h + 1;
 ELSE
 SET p_h = 0;
 END IF;
 END IF;
END;
//

DROP PROCEDURE prng.nistctr_block_encrypt//
CREATE DEFINER = 'prng'@'localhost'
PROCEDURE prng.nistctr_block_encrypt (p_vh BIGINT UNSIGNED, p_vl BIGINT UNSIGNED, p_kh BIGINT UNSIGNED, p_kl BIGINT UNSIGNED, OUT o_h BIGINT UNSIGNED, OUT o_l BIGINT UNSIGNED)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 DECLARE hexblock TEXT;

 SET hexblock = HEX( AES_ENCRYPT(prng.make_128bit_block(p_vh, p_vl), prng.make_128bit_block(p_kh, p_kl)) );
 SET o_h = CONV( SUBSTR(hexblock, 1, 16), 16, 10);
 SET o_l = CONV( SUBSTR(hexblock, 17, 16), 16, 10);
END;
//

DROP PROCEDURE prng.nistctr_update//
CREATE DEFINER = 'prng'@'localhost'
PROCEDURE prng.nistctr_update (INOUT p_vh BIGINT UNSIGNED, INOUT p_vl BIGINT UNSIGNED, INOUT p_kh BIGINT UNSIGNED, INOUT p_kl BIGINT UNSIGNED, IN p_dah BIGINT UNSIGNED, IN p_dal BIGINT UNSIGNED, IN p_dbh BIGINT UNSIGNED, IN p_dbl BIGINT UNSIGNED)
LANGUAGE SQL
CONTAINS SQL
NOT DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 DECLARE tah,tal,tbh,tbl BIGINT UNSIGNED DEFAULT 0;

 CALL prng.inc_128bit_value(p_vh, p_vl);
 CALL prng.nistctr_block_encrypt(p_vh, p_vl, p_kh, p_kl, tah, tal);
 CALL prng.inc_128bit_value(p_vh, p_vl);
 CALL prng.nistctr_block_encrypt(p_vh, p_vl, p_kh, p_kl, tbh, tbl);

 SET tah = tah ^ p_dah; SET tal = tal ^ p_dal;
 SET tbh = tbh ^ p_dbh; SET tbl = tbl ^ p_dbl;

 SET p_kh = tah; SET p_kl = tal;
 SET p_vh = tbh; SET p_vl = tbl;
END;
//

DROP PROCEDURE prng.nistctr_instantiate//
CREATE DEFINER = 'prng'@'localhost'
PROCEDURE prng.nistctr_instantiate (INOUT p_vh BIGINT UNSIGNED, INOUT p_vl BIGINT UNSIGNED, INOUT p_kh BIGINT UNSIGNED, INOUT p_kl BIGINT UNSIGNED, IN p_dah BIGINT UNSIGNED, IN p_dal BIGINT UNSIGNED, IN p_dbh BIGINT UNSIGNED, IN p_dbl BIGINT UNSIGNED)
LANGUAGE SQL
MODIFIES SQL DATA
NOT DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 SET p_kh = 0; SET p_kl = 0;
 SET p_vh = 0; SET p_vl = 0;
 CALL prng.nistctr_update(p_vh, p_vl, p_kh, p_kl, p_dah, p_dal, p_dbh, p_dbl);
END;
//

DROP PROCEDURE prng.nistctr_reseed//
CREATE DEFINER = 'prng'@'localhost'
PROCEDURE prng.nistctr_reseed (INOUT p_vh BIGINT UNSIGNED, INOUT p_vl BIGINT UNSIGNED, INOUT p_kh BIGINT UNSIGNED, INOUT p_kl BIGINT UNSIGNED, IN p_dah BIGINT UNSIGNED, IN p_dal BIGINT UNSIGNED, IN p_dbh BIGINT UNSIGNED, IN p_dbl BIGINT UNSIGNED)
LANGUAGE SQL
MODIFIES SQL DATA
NOT DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 CALL prng.nistctr_update(p_vh, p_vl, p_kh, p_kl, p_dah, p_dal, p_dbh, p_dbl);
END;
//

DROP PROCEDURE prng.nistctr_generate//
CREATE DEFINER = 'prng'@'localhost'
PROCEDURE prng.nistctr_generate (INOUT p_vh BIGINT UNSIGNED, INOUT p_vl BIGINT UNSIGNED, INOUT p_kh BIGINT UNSIGNED, INOUT p_kl BIGINT UNSIGNED, OUT o_h BIGINT UNSIGNED, OUT o_l BIGINT UNSIGNED, IN p_dah BIGINT UNSIGNED, IN p_dal BIGINT UNSIGNED, IN p_dbh BIGINT UNSIGNED, IN p_dbl BIGINT UNSIGNED)
LANGUAGE SQL
MODIFIES SQL DATA
NOT DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 SET o_h = NULL; SET o_l = NULL;
 IF p_dal IS NULL THEN SET p_dal = 0; END IF;
 IF p_dbh IS NULL THEN SET p_dbh = 0; END IF;
 IF p_dbl IS NULL THEN SET p_dbl = 0; END IF;
 IF p_dah IS NULL THEN
 SET p_dah = 0;
 ELSE
 CALL prng.nistctr_update(p_vh, p_vl, p_kh, p_kl, p_dah, p_dal, p_dbh, p_dbl);
 END IF;

 CALL prng.inc_128bit_value(p_vh, p_vl);
 CALL prng.nistctr_block_encrypt(p_vh, p_vl, p_kh, p_kl, o_h, o_l);

 CALL prng.nistctr_update(p_vh, p_vl, p_kh, p_kl, p_dah, p_dal, p_dbh, p_dbl);

END;
//


DROP FUNCTION arosystem.hex_prng_generate_block//
CREATE DEFINER = 'prng'@'localhost'
FUNCTION arosystem.hex_prng_generate_block ()
RETURNS TEXT
MODIFIES SQL DATA
NOT DETERMINISTIC
SQL SECURITY DEFINER
BEGIN
 DECLARE nvh,nvl,nkh,nkl BIGINT UNSIGNED DEFAULT 0;
 DECLARE oh,ol BIGINT UNSIGNED DEFAULT NULL;

 SELECT vh,vl,kh,kl INTO nvh,nvl,nkh,nkl FROM prng.prng_nistctr_state WHERE usable = TRUE LIMIT 1;

 CALL prng.nistctr_generate(nvh,nvl,nkh,nkl,oh,ol,NULL,NULL,NULL,NULL);

 UPDATE prng.prng_nistctr_state SET vh=nvh,vl=nvl,kh=nkh,kl=nkl, reseed_counter = reseed_counter + 1;

 RETURN HEX( prng.make_128bit_block(oh,ol) );
END;
//

DROP PROCEDURE prng.prng_init_hex//
CREATE DEFINER = 'prng'@'localhost'
PROCEDURE prng.prng_init_hex (hexseed TEXT)
MODIFIES SQL DATA
NOT DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
 DECLARE nvh,nvl,nkh,nkl BIGINT UNSIGNED DEFAULT 0;
 DECLARE dah,dal,dbh,dbl BIGINT UNSIGNED DEFAULT 0;

 SET hexseed = LPAD(hexseed, 64, '0');
 SET dah = CONV( SUBSTR(hexseed, 1, 16), 16, 10);
 SET dal = CONV( SUBSTR(hexseed, 17, 16), 16, 10);
 SET dbh = CONV( SUBSTR(hexseed, 33, 16), 16, 10);
 SET dbl = CONV( SUBSTR(hexseed, 49, 16), 16, 10);

 CALL prng.nistctr_instantiate(nvh,nvl,nkh,nkl,dah,dal,dbh,dbl);

 UPDATE prng.prng_nistctr_state SET vh=nvh,vl=nvl,kh=nkh,kl=nkl, usable = TRUE, reseed_counter = 1;
END;
//

Joe at least imbued a certain something into the dance of bouncing in and out of hex representations; safely passing around the strings, and splitting the 128-bit values into 64-bit chunks, then recombining later. Even the modulo arithmetic, implemented by comparison to a hard-coded representation of 2^641, before either adding 1 or setting it to 0.

Yet, in the razzle-dazzle of the dance, certain teensy things may have slipped from Joes attention. Is that seed the required minimum size? What happens in the presence of concurrency? Oops- looks like two concurrent callerts to hex_prng_generate_block can get the same entropy, making the same updates to the state. Better hope this isnt being used for keying material to protect against eavesdropping, or an attacker can get the same keys by simply talking at the same time. And how is this initialized for the very first time?

Just because it looks like it works, returning good values, in good conditions, isnt enough for crypto. Enjoy Joes masterpiece. It might wake you up better than that cup of coffee as you follow along, but please, dont try this at home.

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/elliptical-curveball

Метки:  

 

Добавить комментарий:
Текст комментария: смайлики

Проверка орфографии: (найти ошибки)

Прикрепить картинку:

 Переводить URL в ссылку
 Подписаться на комментарии
 Подписать картинку