summaryrefslogtreecommitdiff
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2014-06-19 10:32:07 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2014-06-19 10:51:21 (UTC)
commita6852c93138f3c4596fb4df8bce5b7d19ef50478 (patch) (unidiff)
tree6a8cfda52d54ae8990a0c51447980d06408ac6cc
parent0422224521f62da210d1ae6ee15ecdf09f47f1f8 (diff)
downloadclipperz-a6852c93138f3c4596fb4df8bce5b7d19ef50478.zip
clipperz-a6852c93138f3c4596fb4df8bce5b7d19ef50478.tar.gz
clipperz-a6852c93138f3c4596fb4df8bce5b7d19ef50478.tar.bz2
Mitigation for vulnerability CLP-01-018
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/Crypto/PRNG.js130
-rw-r--r--frontend/delta/js/Clipperz/Crypto/PRNG.js128
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/PRNG.js128
3 files changed, 135 insertions, 251 deletions
diff --git a/frontend/beta/js/Clipperz/Crypto/PRNG.js b/frontend/beta/js/Clipperz/Crypto/PRNG.js
index b5c3f8a..92966d0 100644
--- a/frontend/beta/js/Clipperz/Crypto/PRNG.js
+++ b/frontend/beta/js/Clipperz/Crypto/PRNG.js
@@ -152,278 +152,230 @@ Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
152 __syntaxFix__: "syntax fix" 152 __syntaxFix__: "syntax fix"
153}); 153});
154 154
155//############################################################################# 155//#############################################################################
156 156
157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { 157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
158 args = args || {}; 158 args = args || {};
159 //MochiKit.Base.bindMethods(this); 159 //MochiKit.Base.bindMethods(this);
160 160
161 this._intervalTime = args.intervalTime || 1000; 161 this._intervalTime = args.intervalTime || 1000;
162 162
163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
164 164
165 this.collectEntropy(); 165 this.collectEntropy();
166 return this; 166 return this;
167} 167}
168 168
169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
170 170
171 'intervalTime': function() { 171 'intervalTime': function() {
172 return this._intervalTime; 172 return this._intervalTime;
173 }, 173 },
174 174
175 //------------------------------------------------------------------------- 175 //-------------------------------------------------------------------------
176 176
177 'collectEntropy': function() { 177 'collectEntropy': function() {
178 varnow; 178 varnow;
179 varentropyByte; 179 varentropyByte;
180 var intervalTime; 180 var intervalTime;
181 now = new Date(); 181 now = new Date();
182 entropyByte = (now.getTime() & 0xff); 182 entropyByte = (now.getTime() & 0xff);
183 183
184 intervalTime = this.intervalTime(); 184 intervalTime = this.intervalTime();
185 if (this.boostMode() == true) { 185 if (this.boostMode() == true) {
186 intervalTime = intervalTime / 9; 186 intervalTime = intervalTime / 9;
187 } 187 }
188 188
189 this.updateGeneratorWithValue(entropyByte); 189 this.updateGeneratorWithValue(entropyByte);
190 setTimeout(this.collectEntropy, intervalTime); 190 setTimeout(this.collectEntropy, intervalTime);
191 }, 191 },
192 192
193 //------------------------------------------------------------------------- 193 //-------------------------------------------------------------------------
194 194
195 'numberOfRandomBits': function() { 195 'numberOfRandomBits': function() {
196 return 5; 196 return 5;
197 }, 197 },
198 198
199 //------------------------------------------------------------------------- 199 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 200 __syntaxFix__: "syntax fix"
207}); 201});
208 202
209//***************************************************************************** 203//*****************************************************************************
210 204
211Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { 205Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
212 args = args || {}; 206 args = args || {};
213 207
214 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 208 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
215 209
216 this._numberOfBitsToCollectAtEachEvent = 4; 210 this._numberOfBitsToCollectAtEachEvent = 4;
217 this._randomBitsCollector = 0; 211 this._randomBitsCollector = 0;
218 this._numberOfRandomBitsCollected = 0; 212 this._numberOfRandomBitsCollected = 0;
219 213
220 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); 214 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
221 215
222 return this; 216 return this;
223} 217}
224 218
225Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 219Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
226 220
227 //------------------------------------------------------------------------- 221 //-------------------------------------------------------------------------
228 222
229 'numberOfBitsToCollectAtEachEvent': function() { 223 'numberOfBitsToCollectAtEachEvent': function() {
230 return this._numberOfBitsToCollectAtEachEvent; 224 return this._numberOfBitsToCollectAtEachEvent;
231 }, 225 },
232 226
233 //------------------------------------------------------------------------- 227 //-------------------------------------------------------------------------
234 228
235 'randomBitsCollector': function() { 229 'randomBitsCollector': function() {
236 return this._randomBitsCollector; 230 return this._randomBitsCollector;
237 }, 231 },
238 232
239 'setRandomBitsCollector': function(aValue) { 233 'setRandomBitsCollector': function(aValue) {
240 this._randomBitsCollector = aValue; 234 this._randomBitsCollector = aValue;
241 }, 235 },
242 236
243 'appendRandomBitsToRandomBitsCollector': function(aValue) { 237 'appendRandomBitsToRandomBitsCollector': function(aValue) {
244 var collectedBits; 238 var collectedBits;
245 var numberOfRandomBitsCollected; 239 var numberOfRandomBitsCollected;
246 240
247 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); 241 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
248 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); 242 collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
249 this.setRandomBitsCollector(collectetBits); 243 this.setRandomBitsCollector(collectedBits);
250 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); 244 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
251 245
252 if (numberOfRandomBitsCollected == 8) { 246 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 247 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 248 numberOfRandomBitsCollected = 0;
255 this.setRandomBitsCollector(0); 249 this.setRandomBitsCollector(0);
256 } 250 }
257 251
258 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) 252 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
259 }, 253 },
260 254
261 //------------------------------------------------------------------------- 255 //-------------------------------------------------------------------------
262 256
263 'numberOfRandomBitsCollected': function() { 257 'numberOfRandomBitsCollected': function() {
264 return this._numberOfRandomBitsCollected; 258 return this._numberOfRandomBitsCollected;
265 }, 259 },
266 260
267 'setNumberOfRandomBitsCollected': function(aValue) { 261 'setNumberOfRandomBitsCollected': function(aValue) {
268 this._numberOfRandomBitsCollected = aValue; 262 this._numberOfRandomBitsCollected = aValue;
269 }, 263 },
270 264
271 //------------------------------------------------------------------------- 265 //-------------------------------------------------------------------------
272 266
273 'collectEntropy': function(anEvent) { 267 'collectEntropy': function(anEvent) {
274 var mouseLocation; 268 var mouseLocation;
275 var randomBit; 269 var randomBit;
276 var mask; 270 var mask;
277 271
278 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); 272 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
279 273
280 mouseLocation = anEvent.mouse().client; 274 mouseLocation = anEvent.mouse().client;
281 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); 275 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
282 this.appendRandomBitsToRandomBitsCollector(randomBit) 276 this.appendRandomBitsToRandomBitsCollector(randomBit)
283 }, 277 },
284 278
285 //------------------------------------------------------------------------- 279 //-------------------------------------------------------------------------
286 280
287 'numberOfRandomBits': function() { 281 'numberOfRandomBits': function() {
288 return 1; 282 return 1;
289 }, 283 },
290 284
291 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 286 __syntaxFix__: "syntax fix"
299}); 287});
300 288
301//***************************************************************************** 289//*****************************************************************************
302 290
303Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { 291Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
304 args = args || {}; 292 args = args || {};
305 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
306 293
307 this._randomBitsCollector = 0; 294 this._intervalTime = args.intervalTime || 1000;
308 this._numberOfRandomBitsCollected = 0; 295 this._browserCrypto = args.browserCrypto;
309 296
310 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); 297 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311 298
299 this.collectEntropy();
312 return this; 300 return this;
313} 301}
314 302
315Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 303Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
316
317 //-------------------------------------------------------------------------
318
319 'randomBitsCollector': function() {
320 return this._randomBitsCollector;
321 },
322 304
323 'setRandomBitsCollector': function(aValue) { 305 'intervalTime': function() {
324 this._randomBitsCollector = aValue; 306 return this._intervalTime;
325 }, 307 },
326 308
327 'appendRandomBitToRandomBitsCollector': function(aValue) { 309 'browserCrypto': function () {
328 var collectedBits; 310 return this._browserCrypto;
329 var numberOfRandomBitsCollected;
330
331 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
332 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
333 this.setRandomBitsCollector(collectetBits);
334 numberOfRandomBitsCollected ++;
335
336 if (numberOfRandomBitsCollected == 8) {
337 this.updateGeneratorWithValue(collectetBits);
338 numberOfRandomBitsCollected = 0;
339 this.setRandomBitsCollector(0);
340 }
341
342 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
343 }, 311 },
344 312
345 //------------------------------------------------------------------------- 313 //-------------------------------------------------------------------------
346 314
347 'numberOfRandomBitsCollected': function() { 315 'collectEntropy': function() {
348 return this._numberOfRandomBitsCollected; 316 varbytesToCollect;
349 },
350
351 'setNumberOfRandomBitsCollected': function(aValue) {
352 this._numberOfRandomBitsCollected = aValue;
353 },
354 317
355 //------------------------------------------------------------------------- 318 if (this.boostMode() == true) {
319 bytesToCollect = 8;
320 } else {
321 bytesToCollect = 32;
322 }
356 323
357 'collectEntropy': function(anEvent) { 324 var randomValuesArray = new Uint8Array(bytesToCollect);
358/* 325 this.browserCrypto().getRandomValues(randomValuesArray);
359 var mouseLocation; 326 for (var i = 0; i < randomValuesArray.length; i++) {
360 var randomBit; 327 this.updateGeneratorWithValue(randomValuesArray[i]);
361 328 }
362 mouseLocation = anEvent.mouse().client;
363
364 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
365 this.appendRandomBitToRandomBitsCollector(randomBit);
366*/
367 },
368
369 //-------------------------------------------------------------------------
370 329
371 'numberOfRandomBits': function() { 330 setTimeout(this.collectEntropy, this.intervalTime());
372 return 1;
373 }, 331 },
374 332
375 //------------------------------------------------------------------------- 333 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 334 __syntaxFix__: "syntax fix"
383}); 335});
384 336
385//############################################################################# 337//#############################################################################
386 338
387Clipperz.Crypto.PRNG.Fortuna = function(args) { 339Clipperz.Crypto.PRNG.Fortuna = function(args) {
388 vari,c; 340 vari,c;
389 341
390 args = args || {}; 342 args = args || {};
391 343
392 this._key = args.seed || null; 344 this._key = args.seed || null;
393 if (this._key == null) { 345 if (this._key == null) {
394 this._counter = 0; 346 this._counter = 0;
395 this._key = new Clipperz.ByteArray(); 347 this._key = new Clipperz.ByteArray();
396 } else { 348 } else {
397 this._counter = 1; 349 this._counter = 1;
398 } 350 }
399 351
400 this._aesKey = null; 352 this._aesKey = null;
401 353
402 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; 354 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
403 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; 355 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
404 356
405 this._accumulators = []; 357 this._accumulators = [];
406 c = this.numberOfEntropyAccumulators(); 358 c = this.numberOfEntropyAccumulators();
407 for (i=0; i<c; i++) { 359 for (i=0; i<c; i++) {
408 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); 360 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
409 } 361 }
410 362
411 this._randomnessSources = []; 363 this._randomnessSources = [];
412 this._reseedCounter = 0; 364 this._reseedCounter = 0;
413 365
414 return this; 366 return this;
415} 367}
416 368
417Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { 369Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
418 370
419 'toString': function() { 371 'toString': function() {
420 return "Clipperz.Crypto.PRNG.Fortuna"; 372 return "Clipperz.Crypto.PRNG.Fortuna";
421 }, 373 },
422 374
423 //------------------------------------------------------------------------- 375 //-------------------------------------------------------------------------
424 376
425 'key': function() { 377 'key': function() {
426 return this._key; 378 return this._key;
427 }, 379 },
428 380
429 'setKey': function(aValue) { 381 'setKey': function(aValue) {
@@ -562,133 +514,127 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
562 } 514 }
563 515
564 return result; 516 return result;
565 }, 517 },
566 518
567 //------------------------------------------------------------------------- 519 //-------------------------------------------------------------------------
568 520
569 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { 521 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
570 varselectedAccumulator; 522 varselectedAccumulator;
571 523
572 selectedAccumulator = this.accumulators()[aPoolId]; 524 selectedAccumulator = this.accumulators()[aPoolId];
573 selectedAccumulator.addRandomByte(aRandomValue); 525 selectedAccumulator.addRandomByte(aRandomValue);
574 526
575 if (aPoolId == 0) { 527 if (aPoolId == 0) {
576 MochiKit.Signal.signal(this, 'addedRandomByte') 528 MochiKit.Signal.signal(this, 'addedRandomByte')
577 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { 529 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
578 this.reseed(); 530 this.reseed();
579 } 531 }
580 } 532 }
581 }, 533 },
582 534
583 //------------------------------------------------------------------------- 535 //-------------------------------------------------------------------------
584 536
585 'numberOfEntropyAccumulators': function() { 537 'numberOfEntropyAccumulators': function() {
586 return this._numberOfEntropyAccumulators; 538 return this._numberOfEntropyAccumulators;
587 }, 539 },
588 540
589 //------------------------------------------------------------------------- 541 //-------------------------------------------------------------------------
590 542
591 'randomnessSources': function() { 543 'randomnessSources': function() {
592 return this._randomnessSources; 544 return this._randomnessSources;
593 }, 545 },
594 546
595 'addRandomnessSource': function(aRandomnessSource) { 547 'addRandomnessSource': function(aRandomnessSource) {
596 aRandomnessSource.setGenerator(this); 548 aRandomnessSource.setGenerator(this);
597 aRandomnessSource.setSourceId(this.randomnessSources().length); 549 aRandomnessSource.setSourceId(this.randomnessSources().length);
598 this.randomnessSources().push(aRandomnessSource); 550 this.randomnessSources().push(aRandomnessSource);
599 551
600 if (this.isReadyToGenerateRandomValues() == false) { 552 if (this.isReadyToGenerateRandomValues() == false) {
601 aRandomnessSource.setBoostMode(true); 553 aRandomnessSource.setBoostMode(true);
602 } 554 }
603 }, 555 },
604 556
605 //------------------------------------------------------------------------- 557 //-------------------------------------------------------------------------
606 558
607 'deferredEntropyCollection': function(aValue) { 559 'deferredEntropyCollection': function(aValue) {
608 var result; 560 var result;
609 561
610//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
611 562
612 if (this.isReadyToGenerateRandomValues()) { 563 if (this.isReadyToGenerateRandomValues()) {
613//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
614 result = aValue; 564 result = aValue;
615 } else { 565 } else {
616//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
617 var deferredResult; 566 var deferredResult;
618 567
619 Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true); 568 Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
620 569
621 deferredResult = new MochiKit.Async.Deferred(); 570 deferredResult = new MochiKit.Async.Deferred();
622 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
623 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); 571 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
624 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
625 MochiKit.Signal.connect(this, 572 MochiKit.Signal.connect(this,
626 'readyToGenerateRandomBytes', 573 'readyToGenerateRandomBytes',
627 deferredResult, 574 deferredResult,
628 'callback'); 575 'callback');
629 576
630 result = deferredResult; 577 result = deferredResult;
631 } 578 }
632//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
633 579
634 return result; 580 return result;
635 }, 581 },
636 582
637 //------------------------------------------------------------------------- 583 //-------------------------------------------------------------------------
638 584
639 'fastEntropyAccumulationForTestingPurpose': function() { 585 'fastEntropyAccumulationForTestingPurpose': function() {
640 while (! this.isReadyToGenerateRandomValues()) { 586 while (! this.isReadyToGenerateRandomValues()) {
641 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); 587 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
642 } 588 }
643 }, 589 },
644 590
645 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
646 592/*
647 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
648 var tbl; 594 var tbl;
649 var i,c; 595 var i,c;
650 596
651 tbl = document.createElement("table"); 597 tbl = document.createElement("table");
652 tbl.border = 0; 598 tbl.border = 0;
653 with (tbl.style) { 599 with (tbl.style) {
654 border = "1px solid lightgrey"; 600 border = "1px solid lightgrey";
655 fontFamily = 'Helvetica, Arial, sans-serif'; 601 fontFamily = 'Helvetica, Arial, sans-serif';
656 fontSize = '8pt'; 602 fontSize = '8pt';
657 //borderCollapse = "collapse"; 603 //borderCollapse = "collapse";
658 } 604 }
659 var hdr = tbl.createTHead(); 605 var hdr = tbl.createTHead();
660 var hdrtr = hdr.insertRow(0); 606 var hdrtr = hdr.insertRow(0);
661 // document.createElement("tr"); 607 // document.createElement("tr");
662 { 608 {
663 var ntd; 609 var ntd;
664 610
665 ntd = hdrtr.insertCell(0); 611 ntd = hdrtr.insertCell(0);
666 ntd.style.borderBottom = "1px solid lightgrey"; 612 ntd.style.borderBottom = "1px solid lightgrey";
667 ntd.style.borderRight = "1px solid lightgrey"; 613 ntd.style.borderRight = "1px solid lightgrey";
668 ntd.appendChild(document.createTextNode("#")); 614 ntd.appendChild(document.createTextNode("#"));
669 615
670 ntd = hdrtr.insertCell(1); 616 ntd = hdrtr.insertCell(1);
671 ntd.style.borderBottom = "1px solid lightgrey"; 617 ntd.style.borderBottom = "1px solid lightgrey";
672 ntd.style.borderRight = "1px solid lightgrey"; 618 ntd.style.borderRight = "1px solid lightgrey";
673 ntd.appendChild(document.createTextNode("s")); 619 ntd.appendChild(document.createTextNode("s"));
674 620
675 ntd = hdrtr.insertCell(2); 621 ntd = hdrtr.insertCell(2);
676 ntd.colSpan = this.firstPoolReseedLevel(); 622 ntd.colSpan = this.firstPoolReseedLevel();
677 ntd.style.borderBottom = "1px solid lightgrey"; 623 ntd.style.borderBottom = "1px solid lightgrey";
678 ntd.style.borderRight = "1px solid lightgrey"; 624 ntd.style.borderRight = "1px solid lightgrey";
679 ntd.appendChild(document.createTextNode("base values")); 625 ntd.appendChild(document.createTextNode("base values"));
680 626
681 ntd = hdrtr.insertCell(3); 627 ntd = hdrtr.insertCell(3);
682 ntd.colSpan = 20; 628 ntd.colSpan = 20;
683 ntd.style.borderBottom = "1px solid lightgrey"; 629 ntd.style.borderBottom = "1px solid lightgrey";
684 ntd.appendChild(document.createTextNode("extra values")); 630 ntd.appendChild(document.createTextNode("extra values"));
685 631
686 } 632 }
687 633
688 c = this.accumulators().length; 634 c = this.accumulators().length;
689 for (i=0; i<c ; i++) { 635 for (i=0; i<c ; i++) {
690 varcurrentAccumulator; 636 varcurrentAccumulator;
691 var bdytr; 637 var bdytr;
692 var bdytd; 638 var bdytd;
693 var ii, cc; 639 var ii, cc;
694 640
@@ -704,146 +650,156 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
704 bdytd = bdytr.insertCell(1); 650 bdytd = bdytr.insertCell(1);
705 bdytd.style.borderRight = "1px solid lightgrey"; 651 bdytd.style.borderRight = "1px solid lightgrey";
706 bdytd.style.color = "gray"; 652 bdytd.style.color = "gray";
707 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); 653 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
708 654
709 655
710 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); 656 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
711 for (ii=0; ii<cc; ii++) { 657 for (ii=0; ii<cc; ii++) {
712 var cellText; 658 var cellText;
713 659
714 bdytd = bdytr.insertCell(ii + 2); 660 bdytd = bdytr.insertCell(ii + 2);
715 661
716 if (ii < currentAccumulator.stack().length()) { 662 if (ii < currentAccumulator.stack().length()) {
717 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); 663 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
718 } else { 664 } else {
719 cellText = "_"; 665 cellText = "_";
720 } 666 }
721 667
722 if (ii == (this.firstPoolReseedLevel() - 1)) { 668 if (ii == (this.firstPoolReseedLevel() - 1)) {
723 bdytd.style.borderRight = "1px solid lightgrey"; 669 bdytd.style.borderRight = "1px solid lightgrey";
724 } 670 }
725 671
726 bdytd.appendChild(document.createTextNode(cellText)); 672 bdytd.appendChild(document.createTextNode(cellText));
727 } 673 }
728 674
729 } 675 }
730 676
731 677
732 if (appendToDoc) { 678 if (appendToDoc) {
733 var ne = document.createElement("div"); 679 var ne = document.createElement("div");
734 ne.id = "entropyGeneratorStatus"; 680 ne.id = "entropyGeneratorStatus";
735 with (ne.style) { 681 with (ne.style) {
736 fontFamily = "Courier New, monospace"; 682 fontFamily = "Courier New, monospace";
737 fontSize = "12px"; 683 fontSize = "12px";
738 lineHeight = "16px"; 684 lineHeight = "16px";
739 borderTop = "1px solid black"; 685 borderTop = "1px solid black";
740 padding = "10px"; 686 padding = "10px";
741 } 687 }
742 if (document.getElementById(ne.id)) { 688 if (document.getElementById(ne.id)) {
743 MochiKit.DOM.swapDOM(ne.id, ne); 689 MochiKit.DOM.swapDOM(ne.id, ne);
744 } else { 690 } else {
745 document.body.appendChild(ne); 691 document.body.appendChild(ne);
746 } 692 }
747 ne.appendChild(tbl); 693 ne.appendChild(tbl);
748 } 694 }
749 695
750 return tbl; 696 return tbl;
751 }, 697 },
752 698*/
753 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
754 __syntaxFix__: "syntax fix" 700 __syntaxFix__: "syntax fix"
755}); 701});
756 702
757//############################################################################# 703//#############################################################################
758 704
759Clipperz.Crypto.PRNG.Random = function(args) { 705Clipperz.Crypto.PRNG.Random = function(args) {
760 args = args || {}; 706 args = args || {};
761 //MochiKit.Base.bindMethods(this); 707 //MochiKit.Base.bindMethods(this);
762 708
763 return this; 709 return this;
764} 710}
765 711
766Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { 712Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
767 713
768 'toString': function() { 714 'toString': function() {
769 return "Clipperz.Crypto.PRNG.Random"; 715 return "Clipperz.Crypto.PRNG.Random";
770 }, 716 },
771 717
772 //------------------------------------------------------------------------- 718 //-------------------------------------------------------------------------
773 719
774 'getRandomBytes': function(aSize) { 720 'getRandomBytes': function(aSize) {
775//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 721//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
776 varresult; 722 varresult;
777 var i,c; 723 var i,c;
778 724
779 result = new Clipperz.ByteArray() 725 result = new Clipperz.ByteArray()
780 c = aSize || 1; 726 c = aSize || 1;
781 for (i=0; i<c; i++) { 727 for (i=0; i<c; i++) {
782 result.appendByte((Math.random()*255) & 0xff); 728 result.appendByte((Math.random()*255) & 0xff);
783 } 729 }
784 730
785//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 731//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
786 return result; 732 return result;
787 }, 733 },
788 734
789 //------------------------------------------------------------------------- 735 //-------------------------------------------------------------------------
790 __syntaxFix__: "syntax fix" 736 __syntaxFix__: "syntax fix"
791}); 737});
792 738
793//############################################################################# 739//#############################################################################
794 740
795_clipperz_crypt_prng_defaultPRNG = null; 741_clipperz_crypt_prng_defaultPRNG = null;
796 742
797Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { 743Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
798 if (_clipperz_crypt_prng_defaultPRNG == null) { 744 if (_clipperz_crypt_prng_defaultPRNG == null) {
799 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); 745 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
800 746
801 //............................................................. 747 //.............................................................
802 // 748 //
803 // TimeRandomnessSource 749 // TimeRandomnessSource
804 // 750 //
805 //............................................................. 751 //.............................................................
806 { 752 {
807 var newRandomnessSource; 753 var newRandomnessSource;
808 754
809 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); 755 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
810 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 756 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
811 } 757 }
812 758
813 //............................................................. 759 //.............................................................
814 // 760 //
815 // MouseRandomnessSource 761 // MouseRandomnessSource
816 // 762 //
817 //............................................................. 763 //.............................................................
818 { 764 {
819 varnewRandomnessSource; 765 varnewRandomnessSource;
820 766
821 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); 767 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
822 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 768 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
823 } 769 }
824 770
825 //............................................................. 771 //.............................................................
826 // 772 //
827 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
828 // 774 //
829 //............................................................. 775 //.............................................................
830 { 776 {
831 varnewRandomnessSource; 777 varnewRandomnessSource;
778 varbrowserCrypto;
832 779
833 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); 780 if (window.crypto && window.crypto.getRandomValues) {
834 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 781 browserCrypto = window.crypto;
782 } else if (window.msCrypto && window.msCrypto.getRandomValues) {
783 browserCrypto = window.msCrypto;
784 } else {
785 browserCrypto = null;
786 }
787
788 if (browserCrypto != null) {
789 newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto});
790 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
791 }
835 } 792 }
836
837 } 793 }
838 794
839 return _clipperz_crypt_prng_defaultPRNG; 795 return _clipperz_crypt_prng_defaultPRNG;
840}; 796};
841 797
842//############################################################################# 798//#############################################################################
843 799
844Clipperz.Crypto.PRNG.exception = { 800Clipperz.Crypto.PRNG.exception = {
845 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") 801 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
846}; 802};
847 803
848 804
849MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); 805MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/delta/js/Clipperz/Crypto/PRNG.js b/frontend/delta/js/Clipperz/Crypto/PRNG.js
index c539f06..7885429 100644
--- a/frontend/delta/js/Clipperz/Crypto/PRNG.js
+++ b/frontend/delta/js/Clipperz/Crypto/PRNG.js
@@ -1,71 +1,73 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24"use strict";
25
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 26try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; 27 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26} 28}
27 29
28try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { 30try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; 31 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
30} 32}
31 33
32try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { 34try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; 35 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
34} 36}
35 37
36if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } 38if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
37 39
38//############################################################################# 40//#############################################################################
39 41
40Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { 42Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
41 args = args || {}; 43 args = args || {};
42 //MochiKit.Base.bindMethods(this); 44 //MochiKit.Base.bindMethods(this);
43 45
44 this._stack = new Clipperz.ByteArray(); 46 this._stack = new Clipperz.ByteArray();
45 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; 47 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
46 return this; 48 return this;
47} 49}
48 50
49Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { 51Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
50 52
51 'toString': function() { 53 'toString': function() {
52 return "Clipperz.Crypto.PRNG.EntropyAccumulator"; 54 return "Clipperz.Crypto.PRNG.EntropyAccumulator";
53 }, 55 },
54 56
55 //------------------------------------------------------------------------- 57 //-------------------------------------------------------------------------
56 58
57 'stack': function() { 59 'stack': function() {
58 return this._stack; 60 return this._stack;
59 }, 61 },
60 62
61 'setStack': function(aValue) { 63 'setStack': function(aValue) {
62 this._stack = aValue; 64 this._stack = aValue;
63 }, 65 },
64 66
65 'resetStack': function() { 67 'resetStack': function() {
66 this.stack().reset(); 68 this.stack().reset();
67 }, 69 },
68 70
69 'maxStackLengthBeforeHashing': function() { 71 'maxStackLengthBeforeHashing': function() {
70 return this._maxStackLengthBeforeHashing; 72 return this._maxStackLengthBeforeHashing;
71 }, 73 },
@@ -152,278 +154,230 @@ Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
152 __syntaxFix__: "syntax fix" 154 __syntaxFix__: "syntax fix"
153}); 155});
154 156
155//############################################################################# 157//#############################################################################
156 158
157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { 159Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
158 args = args || {}; 160 args = args || {};
159 //MochiKit.Base.bindMethods(this); 161 //MochiKit.Base.bindMethods(this);
160 162
161 this._intervalTime = args.intervalTime || 1000; 163 this._intervalTime = args.intervalTime || 1000;
162 164
163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 165 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
164 166
165 this.collectEntropy(); 167 this.collectEntropy();
166 return this; 168 return this;
167} 169}
168 170
169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 171Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
170 172
171 'intervalTime': function() { 173 'intervalTime': function() {
172 return this._intervalTime; 174 return this._intervalTime;
173 }, 175 },
174 176
175 //------------------------------------------------------------------------- 177 //-------------------------------------------------------------------------
176 178
177 'collectEntropy': function() { 179 'collectEntropy': function() {
178 varnow; 180 varnow;
179 varentropyByte; 181 varentropyByte;
180 var intervalTime; 182 var intervalTime;
181 now = new Date(); 183 now = new Date();
182 entropyByte = (now.getTime() & 0xff); 184 entropyByte = (now.getTime() & 0xff);
183 185
184 intervalTime = this.intervalTime(); 186 intervalTime = this.intervalTime();
185 if (this.boostMode() == true) { 187 if (this.boostMode() == true) {
186 intervalTime = intervalTime / 9; 188 intervalTime = intervalTime / 9;
187 } 189 }
188 190
189 this.updateGeneratorWithValue(entropyByte); 191 this.updateGeneratorWithValue(entropyByte);
190 setTimeout(this.collectEntropy, intervalTime); 192 setTimeout(this.collectEntropy, intervalTime);
191 }, 193 },
192 194
193 //------------------------------------------------------------------------- 195 //-------------------------------------------------------------------------
194 196
195 'numberOfRandomBits': function() { 197 'numberOfRandomBits': function() {
196 return 5; 198 return 5;
197 }, 199 },
198 200
199 //------------------------------------------------------------------------- 201 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 202 __syntaxFix__: "syntax fix"
207}); 203});
208 204
209//***************************************************************************** 205//*****************************************************************************
210 206
211Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { 207Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
212 args = args || {}; 208 args = args || {};
213 209
214 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 210 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
215 211
216 this._numberOfBitsToCollectAtEachEvent = 4; 212 this._numberOfBitsToCollectAtEachEvent = 4;
217 this._randomBitsCollector = 0; 213 this._randomBitsCollector = 0;
218 this._numberOfRandomBitsCollected = 0; 214 this._numberOfRandomBitsCollected = 0;
219 215
220 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); 216 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
221 217
222 return this; 218 return this;
223} 219}
224 220
225Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 221Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
226 222
227 //------------------------------------------------------------------------- 223 //-------------------------------------------------------------------------
228 224
229 'numberOfBitsToCollectAtEachEvent': function() { 225 'numberOfBitsToCollectAtEachEvent': function() {
230 return this._numberOfBitsToCollectAtEachEvent; 226 return this._numberOfBitsToCollectAtEachEvent;
231 }, 227 },
232 228
233 //------------------------------------------------------------------------- 229 //-------------------------------------------------------------------------
234 230
235 'randomBitsCollector': function() { 231 'randomBitsCollector': function() {
236 return this._randomBitsCollector; 232 return this._randomBitsCollector;
237 }, 233 },
238 234
239 'setRandomBitsCollector': function(aValue) { 235 'setRandomBitsCollector': function(aValue) {
240 this._randomBitsCollector = aValue; 236 this._randomBitsCollector = aValue;
241 }, 237 },
242 238
243 'appendRandomBitsToRandomBitsCollector': function(aValue) { 239 'appendRandomBitsToRandomBitsCollector': function(aValue) {
244 var collectedBits; 240 var collectedBits;
245 var numberOfRandomBitsCollected; 241 var numberOfRandomBitsCollected;
246 242
247 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); 243 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
248 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); 244 collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
249 this.setRandomBitsCollector(collectetBits); 245 this.setRandomBitsCollector(collectedBits);
250 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); 246 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
251 247
252 if (numberOfRandomBitsCollected == 8) { 248 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 249 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 250 numberOfRandomBitsCollected = 0;
255 this.setRandomBitsCollector(0); 251 this.setRandomBitsCollector(0);
256 } 252 }
257 253
258 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) 254 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
259 }, 255 },
260 256
261 //------------------------------------------------------------------------- 257 //-------------------------------------------------------------------------
262 258
263 'numberOfRandomBitsCollected': function() { 259 'numberOfRandomBitsCollected': function() {
264 return this._numberOfRandomBitsCollected; 260 return this._numberOfRandomBitsCollected;
265 }, 261 },
266 262
267 'setNumberOfRandomBitsCollected': function(aValue) { 263 'setNumberOfRandomBitsCollected': function(aValue) {
268 this._numberOfRandomBitsCollected = aValue; 264 this._numberOfRandomBitsCollected = aValue;
269 }, 265 },
270 266
271 //------------------------------------------------------------------------- 267 //-------------------------------------------------------------------------
272 268
273 'collectEntropy': function(anEvent) { 269 'collectEntropy': function(anEvent) {
274 var mouseLocation; 270 var mouseLocation;
275 var randomBit; 271 var randomBit;
276 var mask; 272 var mask;
277 273
278 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); 274 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
279 275
280 mouseLocation = anEvent.mouse().client; 276 mouseLocation = anEvent.mouse().client;
281 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); 277 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
282 this.appendRandomBitsToRandomBitsCollector(randomBit) 278 this.appendRandomBitsToRandomBitsCollector(randomBit)
283 }, 279 },
284 280
285 //------------------------------------------------------------------------- 281 //-------------------------------------------------------------------------
286 282
287 'numberOfRandomBits': function() { 283 'numberOfRandomBits': function() {
288 return 1; 284 return 1;
289 }, 285 },
290 286
291 //------------------------------------------------------------------------- 287 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 288 __syntaxFix__: "syntax fix"
299}); 289});
300 290
301//***************************************************************************** 291//*****************************************************************************
302 292
303Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { 293Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
304 args = args || {}; 294 args = args || {};
305 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
306 295
307 this._randomBitsCollector = 0; 296 this._intervalTime = args.intervalTime || 1000;
308 this._numberOfRandomBitsCollected = 0; 297 this._browserCrypto = args.browserCrypto;
309 298
310 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); 299 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311 300
301 this.collectEntropy();
312 return this; 302 return this;
313} 303}
314 304
315Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 305Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
316 306
317 //------------------------------------------------------------------------- 307 'intervalTime': function() {
318 308 return this._intervalTime;
319 'randomBitsCollector': function() {
320 return this._randomBitsCollector;
321 },
322
323 'setRandomBitsCollector': function(aValue) {
324 this._randomBitsCollector = aValue;
325 }, 309 },
326 310
327 'appendRandomBitToRandomBitsCollector': function(aValue) { 311 'browserCrypto': function () {
328 var collectedBits; 312 return this._browserCrypto;
329 var numberOfRandomBitsCollected;
330
331 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
332 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
333 this.setRandomBitsCollector(collectetBits);
334 numberOfRandomBitsCollected ++;
335
336 if (numberOfRandomBitsCollected == 8) {
337 this.updateGeneratorWithValue(collectetBits);
338 numberOfRandomBitsCollected = 0;
339 this.setRandomBitsCollector(0);
340 }
341
342 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
343 }, 313 },
344 314
345 //------------------------------------------------------------------------- 315 //-------------------------------------------------------------------------
346 316
347 'numberOfRandomBitsCollected': function() { 317 'collectEntropy': function() {
348 return this._numberOfRandomBitsCollected; 318 varbytesToCollect;
349 },
350
351 'setNumberOfRandomBitsCollected': function(aValue) {
352 this._numberOfRandomBitsCollected = aValue;
353 },
354 319
355 //------------------------------------------------------------------------- 320 if (this.boostMode() == true) {
321 bytesToCollect = 8;
322 } else {
323 bytesToCollect = 32;
324 }
356 325
357 'collectEntropy': function(anEvent) { 326 var randomValuesArray = new Uint8Array(bytesToCollect);
358/* 327 this.browserCrypto().getRandomValues(randomValuesArray);
359 var mouseLocation; 328 for (var i = 0; i < randomValuesArray.length; i++) {
360 var randomBit; 329 this.updateGeneratorWithValue(randomValuesArray[i]);
361 330 }
362 mouseLocation = anEvent.mouse().client;
363
364 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
365 this.appendRandomBitToRandomBitsCollector(randomBit);
366*/
367 },
368
369 //-------------------------------------------------------------------------
370 331
371 'numberOfRandomBits': function() { 332 setTimeout(this.collectEntropy, this.intervalTime());
372 return 1;
373 }, 333 },
374 334
375 //------------------------------------------------------------------------- 335 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 336 __syntaxFix__: "syntax fix"
383}); 337});
384 338
385//############################################################################# 339//#############################################################################
386 340
387Clipperz.Crypto.PRNG.Fortuna = function(args) { 341Clipperz.Crypto.PRNG.Fortuna = function(args) {
388 vari,c; 342 vari,c;
389 343
390 args = args || {}; 344 args = args || {};
391 345
392 this._key = args.seed || null; 346 this._key = args.seed || null;
393 if (this._key == null) { 347 if (this._key == null) {
394 this._counter = 0; 348 this._counter = 0;
395 this._key = new Clipperz.ByteArray(); 349 this._key = new Clipperz.ByteArray();
396 } else { 350 } else {
397 this._counter = 1; 351 this._counter = 1;
398 } 352 }
399 353
400 this._aesKey = null; 354 this._aesKey = null;
401 355
402 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; 356 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
403 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; 357 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
404 358
405 this._accumulators = []; 359 this._accumulators = [];
406 c = this.numberOfEntropyAccumulators(); 360 c = this.numberOfEntropyAccumulators();
407 for (i=0; i<c; i++) { 361 for (i=0; i<c; i++) {
408 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); 362 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
409 } 363 }
410 364
411 this._randomnessSources = []; 365 this._randomnessSources = [];
412 this._reseedCounter = 0; 366 this._reseedCounter = 0;
413 367
414 return this; 368 return this;
415} 369}
416 370
417Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { 371Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
418 372
419 'toString': function() { 373 'toString': function() {
420 return "Clipperz.Crypto.PRNG.Fortuna"; 374 return "Clipperz.Crypto.PRNG.Fortuna";
421 }, 375 },
422 376
423 //------------------------------------------------------------------------- 377 //-------------------------------------------------------------------------
424 378
425 'key': function() { 379 'key': function() {
426 return this._key; 380 return this._key;
427 }, 381 },
428 382
429 'setKey': function(aValue) { 383 'setKey': function(aValue) {
@@ -590,97 +544,97 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
590 544
591 'randomnessSources': function() { 545 'randomnessSources': function() {
592 return this._randomnessSources; 546 return this._randomnessSources;
593 }, 547 },
594 548
595 'addRandomnessSource': function(aRandomnessSource) { 549 'addRandomnessSource': function(aRandomnessSource) {
596 aRandomnessSource.setGenerator(this); 550 aRandomnessSource.setGenerator(this);
597 aRandomnessSource.setSourceId(this.randomnessSources().length); 551 aRandomnessSource.setSourceId(this.randomnessSources().length);
598 this.randomnessSources().push(aRandomnessSource); 552 this.randomnessSources().push(aRandomnessSource);
599 553
600 if (this.isReadyToGenerateRandomValues() == false) { 554 if (this.isReadyToGenerateRandomValues() == false) {
601 aRandomnessSource.setBoostMode(true); 555 aRandomnessSource.setBoostMode(true);
602 } 556 }
603 }, 557 },
604 558
605 //------------------------------------------------------------------------- 559 //-------------------------------------------------------------------------
606 560
607 'deferredEntropyCollection': function(aValue) { 561 'deferredEntropyCollection': function(aValue) {
608 var result; 562 var result;
609 563
610 564
611 if (this.isReadyToGenerateRandomValues()) { 565 if (this.isReadyToGenerateRandomValues()) {
612 result = aValue; 566 result = aValue;
613 } else { 567 } else {
614 var deferredResult; 568 var deferredResult;
615 569
616 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection"); 570 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
617 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); 571 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
618 MochiKit.Signal.connect(this, 572 MochiKit.Signal.connect(this,
619 'readyToGenerateRandomBytes', 573 'readyToGenerateRandomBytes',
620 deferredResult, 574 deferredResult,
621 'callback'); 575 'callback');
622 576
623 result = deferredResult; 577 result = deferredResult;
624 } 578 }
625 579
626 return result; 580 return result;
627 }, 581 },
628 582
629 //------------------------------------------------------------------------- 583 //-------------------------------------------------------------------------
630 584
631 'fastEntropyAccumulationForTestingPurpose': function() { 585 'fastEntropyAccumulationForTestingPurpose': function() {
632 while (! this.isReadyToGenerateRandomValues()) { 586 while (! this.isReadyToGenerateRandomValues()) {
633 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); 587 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
634 } 588 }
635 }, 589 },
636 590
637 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
638 592/*
639 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
640 var tbl; 594 var tbl;
641 var i,c; 595 var i,c;
642 596
643 tbl = document.createElement("table"); 597 tbl = document.createElement("table");
644 tbl.border = 0; 598 tbl.border = 0;
645 with (tbl.style) { 599 with (tbl.style) {
646 border = "1px solid lightgrey"; 600 border = "1px solid lightgrey";
647 fontFamily = 'Helvetica, Arial, sans-serif'; 601 fontFamily = 'Helvetica, Arial, sans-serif';
648 fontSize = '8pt'; 602 fontSize = '8pt';
649 //borderCollapse = "collapse"; 603 //borderCollapse = "collapse";
650 } 604 }
651 var hdr = tbl.createTHead(); 605 var hdr = tbl.createTHead();
652 var hdrtr = hdr.insertRow(0); 606 var hdrtr = hdr.insertRow(0);
653 // document.createElement("tr"); 607 // document.createElement("tr");
654 { 608 {
655 var ntd; 609 var ntd;
656 610
657 ntd = hdrtr.insertCell(0); 611 ntd = hdrtr.insertCell(0);
658 ntd.style.borderBottom = "1px solid lightgrey"; 612 ntd.style.borderBottom = "1px solid lightgrey";
659 ntd.style.borderRight = "1px solid lightgrey"; 613 ntd.style.borderRight = "1px solid lightgrey";
660 ntd.appendChild(document.createTextNode("#")); 614 ntd.appendChild(document.createTextNode("#"));
661 615
662 ntd = hdrtr.insertCell(1); 616 ntd = hdrtr.insertCell(1);
663 ntd.style.borderBottom = "1px solid lightgrey"; 617 ntd.style.borderBottom = "1px solid lightgrey";
664 ntd.style.borderRight = "1px solid lightgrey"; 618 ntd.style.borderRight = "1px solid lightgrey";
665 ntd.appendChild(document.createTextNode("s")); 619 ntd.appendChild(document.createTextNode("s"));
666 620
667 ntd = hdrtr.insertCell(2); 621 ntd = hdrtr.insertCell(2);
668 ntd.colSpan = this.firstPoolReseedLevel(); 622 ntd.colSpan = this.firstPoolReseedLevel();
669 ntd.style.borderBottom = "1px solid lightgrey"; 623 ntd.style.borderBottom = "1px solid lightgrey";
670 ntd.style.borderRight = "1px solid lightgrey"; 624 ntd.style.borderRight = "1px solid lightgrey";
671 ntd.appendChild(document.createTextNode("base values")); 625 ntd.appendChild(document.createTextNode("base values"));
672 626
673 ntd = hdrtr.insertCell(3); 627 ntd = hdrtr.insertCell(3);
674 ntd.colSpan = 20; 628 ntd.colSpan = 20;
675 ntd.style.borderBottom = "1px solid lightgrey"; 629 ntd.style.borderBottom = "1px solid lightgrey";
676 ntd.appendChild(document.createTextNode("extra values")); 630 ntd.appendChild(document.createTextNode("extra values"));
677 631
678 } 632 }
679 633
680 c = this.accumulators().length; 634 c = this.accumulators().length;
681 for (i=0; i<c ; i++) { 635 for (i=0; i<c ; i++) {
682 varcurrentAccumulator; 636 varcurrentAccumulator;
683 var bdytr; 637 var bdytr;
684 var bdytd; 638 var bdytd;
685 var ii, cc; 639 var ii, cc;
686 640
@@ -696,146 +650,156 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
696 bdytd = bdytr.insertCell(1); 650 bdytd = bdytr.insertCell(1);
697 bdytd.style.borderRight = "1px solid lightgrey"; 651 bdytd.style.borderRight = "1px solid lightgrey";
698 bdytd.style.color = "gray"; 652 bdytd.style.color = "gray";
699 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); 653 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
700 654
701 655
702 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); 656 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
703 for (ii=0; ii<cc; ii++) { 657 for (ii=0; ii<cc; ii++) {
704 var cellText; 658 var cellText;
705 659
706 bdytd = bdytr.insertCell(ii + 2); 660 bdytd = bdytr.insertCell(ii + 2);
707 661
708 if (ii < currentAccumulator.stack().length()) { 662 if (ii < currentAccumulator.stack().length()) {
709 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); 663 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
710 } else { 664 } else {
711 cellText = "_"; 665 cellText = "_";
712 } 666 }
713 667
714 if (ii == (this.firstPoolReseedLevel() - 1)) { 668 if (ii == (this.firstPoolReseedLevel() - 1)) {
715 bdytd.style.borderRight = "1px solid lightgrey"; 669 bdytd.style.borderRight = "1px solid lightgrey";
716 } 670 }
717 671
718 bdytd.appendChild(document.createTextNode(cellText)); 672 bdytd.appendChild(document.createTextNode(cellText));
719 } 673 }
720 674
721 } 675 }
722 676
723 677
724 if (appendToDoc) { 678 if (appendToDoc) {
725 var ne = document.createElement("div"); 679 var ne = document.createElement("div");
726 ne.id = "entropyGeneratorStatus"; 680 ne.id = "entropyGeneratorStatus";
727 with (ne.style) { 681 with (ne.style) {
728 fontFamily = "Courier New, monospace"; 682 fontFamily = "Courier New, monospace";
729 fontSize = "12px"; 683 fontSize = "12px";
730 lineHeight = "16px"; 684 lineHeight = "16px";
731 borderTop = "1px solid black"; 685 borderTop = "1px solid black";
732 padding = "10px"; 686 padding = "10px";
733 } 687 }
734 if (document.getElementById(ne.id)) { 688 if (document.getElementById(ne.id)) {
735 MochiKit.DOM.swapDOM(ne.id, ne); 689 MochiKit.DOM.swapDOM(ne.id, ne);
736 } else { 690 } else {
737 document.body.appendChild(ne); 691 document.body.appendChild(ne);
738 } 692 }
739 ne.appendChild(tbl); 693 ne.appendChild(tbl);
740 } 694 }
741 695
742 return tbl; 696 return tbl;
743 }, 697 },
744 698*/
745 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
746 __syntaxFix__: "syntax fix" 700 __syntaxFix__: "syntax fix"
747}); 701});
748 702
749//############################################################################# 703//#############################################################################
750 704
751Clipperz.Crypto.PRNG.Random = function(args) { 705Clipperz.Crypto.PRNG.Random = function(args) {
752 args = args || {}; 706 args = args || {};
753 //MochiKit.Base.bindMethods(this); 707 //MochiKit.Base.bindMethods(this);
754 708
755 return this; 709 return this;
756} 710}
757 711
758Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { 712Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
759 713
760 'toString': function() { 714 'toString': function() {
761 return "Clipperz.Crypto.PRNG.Random"; 715 return "Clipperz.Crypto.PRNG.Random";
762 }, 716 },
763 717
764 //------------------------------------------------------------------------- 718 //-------------------------------------------------------------------------
765 719
766 'getRandomBytes': function(aSize) { 720 'getRandomBytes': function(aSize) {
767//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 721//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
768 varresult; 722 varresult;
769 var i,c; 723 var i,c;
770 724
771 result = new Clipperz.ByteArray() 725 result = new Clipperz.ByteArray()
772 c = aSize || 1; 726 c = aSize || 1;
773 for (i=0; i<c; i++) { 727 for (i=0; i<c; i++) {
774 result.appendByte((Math.random()*255) & 0xff); 728 result.appendByte((Math.random()*255) & 0xff);
775 } 729 }
776 730
777//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 731//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
778 return result; 732 return result;
779 }, 733 },
780 734
781 //------------------------------------------------------------------------- 735 //-------------------------------------------------------------------------
782 __syntaxFix__: "syntax fix" 736 __syntaxFix__: "syntax fix"
783}); 737});
784 738
785//############################################################################# 739//#############################################################################
786 740
787_clipperz_crypt_prng_defaultPRNG = null; 741var _clipperz_crypt_prng_defaultPRNG = null;
788 742
789Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { 743Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
790 if (_clipperz_crypt_prng_defaultPRNG == null) { 744 if (_clipperz_crypt_prng_defaultPRNG == null) {
791 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); 745 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
792 746
793 //............................................................. 747 //.............................................................
794 // 748 //
795 // TimeRandomnessSource 749 // TimeRandomnessSource
796 // 750 //
797 //............................................................. 751 //.............................................................
798 { 752 {
799 var newRandomnessSource; 753 var newRandomnessSource;
800 754
801 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); 755 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
802 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 756 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
803 } 757 }
804 758
805 //............................................................. 759 //.............................................................
806 // 760 //
807 // MouseRandomnessSource 761 // MouseRandomnessSource
808 // 762 //
809 //............................................................. 763 //.............................................................
810 { 764 {
811 varnewRandomnessSource; 765 varnewRandomnessSource;
812 766
813 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); 767 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
814 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 768 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
815 } 769 }
816 770
817 //............................................................. 771 //.............................................................
818 // 772 //
819 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
820 // 774 //
821 //............................................................. 775 //.............................................................
822 { 776 {
823 varnewRandomnessSource; 777 varnewRandomnessSource;
778 varbrowserCrypto;
824 779
825 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); 780 if (window.crypto && window.crypto.getRandomValues) {
826 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 781 browserCrypto = window.crypto;
782 } else if (window.msCrypto && window.msCrypto.getRandomValues) {
783 browserCrypto = window.msCrypto;
784 } else {
785 browserCrypto = null;
786 }
787
788 if (browserCrypto != null) {
789 newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto});
790 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
791 }
827 } 792 }
828
829 } 793 }
830 794
831 return _clipperz_crypt_prng_defaultPRNG; 795 return _clipperz_crypt_prng_defaultPRNG;
832}; 796};
833 797
834//############################################################################# 798//#############################################################################
835 799
836Clipperz.Crypto.PRNG.exception = { 800Clipperz.Crypto.PRNG.exception = {
837 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") 801 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
838}; 802};
839 803
840 804
841MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); 805MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/gamma/js/Clipperz/Crypto/PRNG.js b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
index c539f06..7885429 100644
--- a/frontend/gamma/js/Clipperz/Crypto/PRNG.js
+++ b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
@@ -1,71 +1,73 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24"use strict";
25
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 26try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; 27 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26} 28}
27 29
28try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { 30try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; 31 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
30} 32}
31 33
32try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { 34try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; 35 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
34} 36}
35 37
36if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } 38if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
37 39
38//############################################################################# 40//#############################################################################
39 41
40Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { 42Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
41 args = args || {}; 43 args = args || {};
42 //MochiKit.Base.bindMethods(this); 44 //MochiKit.Base.bindMethods(this);
43 45
44 this._stack = new Clipperz.ByteArray(); 46 this._stack = new Clipperz.ByteArray();
45 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; 47 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
46 return this; 48 return this;
47} 49}
48 50
49Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { 51Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
50 52
51 'toString': function() { 53 'toString': function() {
52 return "Clipperz.Crypto.PRNG.EntropyAccumulator"; 54 return "Clipperz.Crypto.PRNG.EntropyAccumulator";
53 }, 55 },
54 56
55 //------------------------------------------------------------------------- 57 //-------------------------------------------------------------------------
56 58
57 'stack': function() { 59 'stack': function() {
58 return this._stack; 60 return this._stack;
59 }, 61 },
60 62
61 'setStack': function(aValue) { 63 'setStack': function(aValue) {
62 this._stack = aValue; 64 this._stack = aValue;
63 }, 65 },
64 66
65 'resetStack': function() { 67 'resetStack': function() {
66 this.stack().reset(); 68 this.stack().reset();
67 }, 69 },
68 70
69 'maxStackLengthBeforeHashing': function() { 71 'maxStackLengthBeforeHashing': function() {
70 return this._maxStackLengthBeforeHashing; 72 return this._maxStackLengthBeforeHashing;
71 }, 73 },
@@ -152,278 +154,230 @@ Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
152 __syntaxFix__: "syntax fix" 154 __syntaxFix__: "syntax fix"
153}); 155});
154 156
155//############################################################################# 157//#############################################################################
156 158
157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { 159Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
158 args = args || {}; 160 args = args || {};
159 //MochiKit.Base.bindMethods(this); 161 //MochiKit.Base.bindMethods(this);
160 162
161 this._intervalTime = args.intervalTime || 1000; 163 this._intervalTime = args.intervalTime || 1000;
162 164
163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 165 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
164 166
165 this.collectEntropy(); 167 this.collectEntropy();
166 return this; 168 return this;
167} 169}
168 170
169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 171Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
170 172
171 'intervalTime': function() { 173 'intervalTime': function() {
172 return this._intervalTime; 174 return this._intervalTime;
173 }, 175 },
174 176
175 //------------------------------------------------------------------------- 177 //-------------------------------------------------------------------------
176 178
177 'collectEntropy': function() { 179 'collectEntropy': function() {
178 varnow; 180 varnow;
179 varentropyByte; 181 varentropyByte;
180 var intervalTime; 182 var intervalTime;
181 now = new Date(); 183 now = new Date();
182 entropyByte = (now.getTime() & 0xff); 184 entropyByte = (now.getTime() & 0xff);
183 185
184 intervalTime = this.intervalTime(); 186 intervalTime = this.intervalTime();
185 if (this.boostMode() == true) { 187 if (this.boostMode() == true) {
186 intervalTime = intervalTime / 9; 188 intervalTime = intervalTime / 9;
187 } 189 }
188 190
189 this.updateGeneratorWithValue(entropyByte); 191 this.updateGeneratorWithValue(entropyByte);
190 setTimeout(this.collectEntropy, intervalTime); 192 setTimeout(this.collectEntropy, intervalTime);
191 }, 193 },
192 194
193 //------------------------------------------------------------------------- 195 //-------------------------------------------------------------------------
194 196
195 'numberOfRandomBits': function() { 197 'numberOfRandomBits': function() {
196 return 5; 198 return 5;
197 }, 199 },
198 200
199 //------------------------------------------------------------------------- 201 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 202 __syntaxFix__: "syntax fix"
207}); 203});
208 204
209//***************************************************************************** 205//*****************************************************************************
210 206
211Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { 207Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
212 args = args || {}; 208 args = args || {};
213 209
214 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 210 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
215 211
216 this._numberOfBitsToCollectAtEachEvent = 4; 212 this._numberOfBitsToCollectAtEachEvent = 4;
217 this._randomBitsCollector = 0; 213 this._randomBitsCollector = 0;
218 this._numberOfRandomBitsCollected = 0; 214 this._numberOfRandomBitsCollected = 0;
219 215
220 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); 216 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
221 217
222 return this; 218 return this;
223} 219}
224 220
225Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 221Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
226 222
227 //------------------------------------------------------------------------- 223 //-------------------------------------------------------------------------
228 224
229 'numberOfBitsToCollectAtEachEvent': function() { 225 'numberOfBitsToCollectAtEachEvent': function() {
230 return this._numberOfBitsToCollectAtEachEvent; 226 return this._numberOfBitsToCollectAtEachEvent;
231 }, 227 },
232 228
233 //------------------------------------------------------------------------- 229 //-------------------------------------------------------------------------
234 230
235 'randomBitsCollector': function() { 231 'randomBitsCollector': function() {
236 return this._randomBitsCollector; 232 return this._randomBitsCollector;
237 }, 233 },
238 234
239 'setRandomBitsCollector': function(aValue) { 235 'setRandomBitsCollector': function(aValue) {
240 this._randomBitsCollector = aValue; 236 this._randomBitsCollector = aValue;
241 }, 237 },
242 238
243 'appendRandomBitsToRandomBitsCollector': function(aValue) { 239 'appendRandomBitsToRandomBitsCollector': function(aValue) {
244 var collectedBits; 240 var collectedBits;
245 var numberOfRandomBitsCollected; 241 var numberOfRandomBitsCollected;
246 242
247 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); 243 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
248 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); 244 collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
249 this.setRandomBitsCollector(collectetBits); 245 this.setRandomBitsCollector(collectedBits);
250 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); 246 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
251 247
252 if (numberOfRandomBitsCollected == 8) { 248 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 249 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 250 numberOfRandomBitsCollected = 0;
255 this.setRandomBitsCollector(0); 251 this.setRandomBitsCollector(0);
256 } 252 }
257 253
258 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) 254 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
259 }, 255 },
260 256
261 //------------------------------------------------------------------------- 257 //-------------------------------------------------------------------------
262 258
263 'numberOfRandomBitsCollected': function() { 259 'numberOfRandomBitsCollected': function() {
264 return this._numberOfRandomBitsCollected; 260 return this._numberOfRandomBitsCollected;
265 }, 261 },
266 262
267 'setNumberOfRandomBitsCollected': function(aValue) { 263 'setNumberOfRandomBitsCollected': function(aValue) {
268 this._numberOfRandomBitsCollected = aValue; 264 this._numberOfRandomBitsCollected = aValue;
269 }, 265 },
270 266
271 //------------------------------------------------------------------------- 267 //-------------------------------------------------------------------------
272 268
273 'collectEntropy': function(anEvent) { 269 'collectEntropy': function(anEvent) {
274 var mouseLocation; 270 var mouseLocation;
275 var randomBit; 271 var randomBit;
276 var mask; 272 var mask;
277 273
278 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); 274 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
279 275
280 mouseLocation = anEvent.mouse().client; 276 mouseLocation = anEvent.mouse().client;
281 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); 277 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
282 this.appendRandomBitsToRandomBitsCollector(randomBit) 278 this.appendRandomBitsToRandomBitsCollector(randomBit)
283 }, 279 },
284 280
285 //------------------------------------------------------------------------- 281 //-------------------------------------------------------------------------
286 282
287 'numberOfRandomBits': function() { 283 'numberOfRandomBits': function() {
288 return 1; 284 return 1;
289 }, 285 },
290 286
291 //------------------------------------------------------------------------- 287 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 288 __syntaxFix__: "syntax fix"
299}); 289});
300 290
301//***************************************************************************** 291//*****************************************************************************
302 292
303Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { 293Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
304 args = args || {}; 294 args = args || {};
305 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
306 295
307 this._randomBitsCollector = 0; 296 this._intervalTime = args.intervalTime || 1000;
308 this._numberOfRandomBitsCollected = 0; 297 this._browserCrypto = args.browserCrypto;
309 298
310 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); 299 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311 300
301 this.collectEntropy();
312 return this; 302 return this;
313} 303}
314 304
315Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 305Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
316 306
317 //------------------------------------------------------------------------- 307 'intervalTime': function() {
318 308 return this._intervalTime;
319 'randomBitsCollector': function() {
320 return this._randomBitsCollector;
321 },
322
323 'setRandomBitsCollector': function(aValue) {
324 this._randomBitsCollector = aValue;
325 }, 309 },
326 310
327 'appendRandomBitToRandomBitsCollector': function(aValue) { 311 'browserCrypto': function () {
328 var collectedBits; 312 return this._browserCrypto;
329 var numberOfRandomBitsCollected;
330
331 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
332 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
333 this.setRandomBitsCollector(collectetBits);
334 numberOfRandomBitsCollected ++;
335
336 if (numberOfRandomBitsCollected == 8) {
337 this.updateGeneratorWithValue(collectetBits);
338 numberOfRandomBitsCollected = 0;
339 this.setRandomBitsCollector(0);
340 }
341
342 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
343 }, 313 },
344 314
345 //------------------------------------------------------------------------- 315 //-------------------------------------------------------------------------
346 316
347 'numberOfRandomBitsCollected': function() { 317 'collectEntropy': function() {
348 return this._numberOfRandomBitsCollected; 318 varbytesToCollect;
349 },
350
351 'setNumberOfRandomBitsCollected': function(aValue) {
352 this._numberOfRandomBitsCollected = aValue;
353 },
354 319
355 //------------------------------------------------------------------------- 320 if (this.boostMode() == true) {
321 bytesToCollect = 8;
322 } else {
323 bytesToCollect = 32;
324 }
356 325
357 'collectEntropy': function(anEvent) { 326 var randomValuesArray = new Uint8Array(bytesToCollect);
358/* 327 this.browserCrypto().getRandomValues(randomValuesArray);
359 var mouseLocation; 328 for (var i = 0; i < randomValuesArray.length; i++) {
360 var randomBit; 329 this.updateGeneratorWithValue(randomValuesArray[i]);
361 330 }
362 mouseLocation = anEvent.mouse().client;
363
364 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
365 this.appendRandomBitToRandomBitsCollector(randomBit);
366*/
367 },
368
369 //-------------------------------------------------------------------------
370 331
371 'numberOfRandomBits': function() { 332 setTimeout(this.collectEntropy, this.intervalTime());
372 return 1;
373 }, 333 },
374 334
375 //------------------------------------------------------------------------- 335 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 336 __syntaxFix__: "syntax fix"
383}); 337});
384 338
385//############################################################################# 339//#############################################################################
386 340
387Clipperz.Crypto.PRNG.Fortuna = function(args) { 341Clipperz.Crypto.PRNG.Fortuna = function(args) {
388 vari,c; 342 vari,c;
389 343
390 args = args || {}; 344 args = args || {};
391 345
392 this._key = args.seed || null; 346 this._key = args.seed || null;
393 if (this._key == null) { 347 if (this._key == null) {
394 this._counter = 0; 348 this._counter = 0;
395 this._key = new Clipperz.ByteArray(); 349 this._key = new Clipperz.ByteArray();
396 } else { 350 } else {
397 this._counter = 1; 351 this._counter = 1;
398 } 352 }
399 353
400 this._aesKey = null; 354 this._aesKey = null;
401 355
402 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; 356 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
403 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; 357 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
404 358
405 this._accumulators = []; 359 this._accumulators = [];
406 c = this.numberOfEntropyAccumulators(); 360 c = this.numberOfEntropyAccumulators();
407 for (i=0; i<c; i++) { 361 for (i=0; i<c; i++) {
408 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); 362 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
409 } 363 }
410 364
411 this._randomnessSources = []; 365 this._randomnessSources = [];
412 this._reseedCounter = 0; 366 this._reseedCounter = 0;
413 367
414 return this; 368 return this;
415} 369}
416 370
417Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { 371Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
418 372
419 'toString': function() { 373 'toString': function() {
420 return "Clipperz.Crypto.PRNG.Fortuna"; 374 return "Clipperz.Crypto.PRNG.Fortuna";
421 }, 375 },
422 376
423 //------------------------------------------------------------------------- 377 //-------------------------------------------------------------------------
424 378
425 'key': function() { 379 'key': function() {
426 return this._key; 380 return this._key;
427 }, 381 },
428 382
429 'setKey': function(aValue) { 383 'setKey': function(aValue) {
@@ -590,97 +544,97 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
590 544
591 'randomnessSources': function() { 545 'randomnessSources': function() {
592 return this._randomnessSources; 546 return this._randomnessSources;
593 }, 547 },
594 548
595 'addRandomnessSource': function(aRandomnessSource) { 549 'addRandomnessSource': function(aRandomnessSource) {
596 aRandomnessSource.setGenerator(this); 550 aRandomnessSource.setGenerator(this);
597 aRandomnessSource.setSourceId(this.randomnessSources().length); 551 aRandomnessSource.setSourceId(this.randomnessSources().length);
598 this.randomnessSources().push(aRandomnessSource); 552 this.randomnessSources().push(aRandomnessSource);
599 553
600 if (this.isReadyToGenerateRandomValues() == false) { 554 if (this.isReadyToGenerateRandomValues() == false) {
601 aRandomnessSource.setBoostMode(true); 555 aRandomnessSource.setBoostMode(true);
602 } 556 }
603 }, 557 },
604 558
605 //------------------------------------------------------------------------- 559 //-------------------------------------------------------------------------
606 560
607 'deferredEntropyCollection': function(aValue) { 561 'deferredEntropyCollection': function(aValue) {
608 var result; 562 var result;
609 563
610 564
611 if (this.isReadyToGenerateRandomValues()) { 565 if (this.isReadyToGenerateRandomValues()) {
612 result = aValue; 566 result = aValue;
613 } else { 567 } else {
614 var deferredResult; 568 var deferredResult;
615 569
616 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection"); 570 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
617 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); 571 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
618 MochiKit.Signal.connect(this, 572 MochiKit.Signal.connect(this,
619 'readyToGenerateRandomBytes', 573 'readyToGenerateRandomBytes',
620 deferredResult, 574 deferredResult,
621 'callback'); 575 'callback');
622 576
623 result = deferredResult; 577 result = deferredResult;
624 } 578 }
625 579
626 return result; 580 return result;
627 }, 581 },
628 582
629 //------------------------------------------------------------------------- 583 //-------------------------------------------------------------------------
630 584
631 'fastEntropyAccumulationForTestingPurpose': function() { 585 'fastEntropyAccumulationForTestingPurpose': function() {
632 while (! this.isReadyToGenerateRandomValues()) { 586 while (! this.isReadyToGenerateRandomValues()) {
633 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); 587 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
634 } 588 }
635 }, 589 },
636 590
637 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
638 592/*
639 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
640 var tbl; 594 var tbl;
641 var i,c; 595 var i,c;
642 596
643 tbl = document.createElement("table"); 597 tbl = document.createElement("table");
644 tbl.border = 0; 598 tbl.border = 0;
645 with (tbl.style) { 599 with (tbl.style) {
646 border = "1px solid lightgrey"; 600 border = "1px solid lightgrey";
647 fontFamily = 'Helvetica, Arial, sans-serif'; 601 fontFamily = 'Helvetica, Arial, sans-serif';
648 fontSize = '8pt'; 602 fontSize = '8pt';
649 //borderCollapse = "collapse"; 603 //borderCollapse = "collapse";
650 } 604 }
651 var hdr = tbl.createTHead(); 605 var hdr = tbl.createTHead();
652 var hdrtr = hdr.insertRow(0); 606 var hdrtr = hdr.insertRow(0);
653 // document.createElement("tr"); 607 // document.createElement("tr");
654 { 608 {
655 var ntd; 609 var ntd;
656 610
657 ntd = hdrtr.insertCell(0); 611 ntd = hdrtr.insertCell(0);
658 ntd.style.borderBottom = "1px solid lightgrey"; 612 ntd.style.borderBottom = "1px solid lightgrey";
659 ntd.style.borderRight = "1px solid lightgrey"; 613 ntd.style.borderRight = "1px solid lightgrey";
660 ntd.appendChild(document.createTextNode("#")); 614 ntd.appendChild(document.createTextNode("#"));
661 615
662 ntd = hdrtr.insertCell(1); 616 ntd = hdrtr.insertCell(1);
663 ntd.style.borderBottom = "1px solid lightgrey"; 617 ntd.style.borderBottom = "1px solid lightgrey";
664 ntd.style.borderRight = "1px solid lightgrey"; 618 ntd.style.borderRight = "1px solid lightgrey";
665 ntd.appendChild(document.createTextNode("s")); 619 ntd.appendChild(document.createTextNode("s"));
666 620
667 ntd = hdrtr.insertCell(2); 621 ntd = hdrtr.insertCell(2);
668 ntd.colSpan = this.firstPoolReseedLevel(); 622 ntd.colSpan = this.firstPoolReseedLevel();
669 ntd.style.borderBottom = "1px solid lightgrey"; 623 ntd.style.borderBottom = "1px solid lightgrey";
670 ntd.style.borderRight = "1px solid lightgrey"; 624 ntd.style.borderRight = "1px solid lightgrey";
671 ntd.appendChild(document.createTextNode("base values")); 625 ntd.appendChild(document.createTextNode("base values"));
672 626
673 ntd = hdrtr.insertCell(3); 627 ntd = hdrtr.insertCell(3);
674 ntd.colSpan = 20; 628 ntd.colSpan = 20;
675 ntd.style.borderBottom = "1px solid lightgrey"; 629 ntd.style.borderBottom = "1px solid lightgrey";
676 ntd.appendChild(document.createTextNode("extra values")); 630 ntd.appendChild(document.createTextNode("extra values"));
677 631
678 } 632 }
679 633
680 c = this.accumulators().length; 634 c = this.accumulators().length;
681 for (i=0; i<c ; i++) { 635 for (i=0; i<c ; i++) {
682 varcurrentAccumulator; 636 varcurrentAccumulator;
683 var bdytr; 637 var bdytr;
684 var bdytd; 638 var bdytd;
685 var ii, cc; 639 var ii, cc;
686 640
@@ -696,146 +650,156 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
696 bdytd = bdytr.insertCell(1); 650 bdytd = bdytr.insertCell(1);
697 bdytd.style.borderRight = "1px solid lightgrey"; 651 bdytd.style.borderRight = "1px solid lightgrey";
698 bdytd.style.color = "gray"; 652 bdytd.style.color = "gray";
699 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); 653 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
700 654
701 655
702 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); 656 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
703 for (ii=0; ii<cc; ii++) { 657 for (ii=0; ii<cc; ii++) {
704 var cellText; 658 var cellText;
705 659
706 bdytd = bdytr.insertCell(ii + 2); 660 bdytd = bdytr.insertCell(ii + 2);
707 661
708 if (ii < currentAccumulator.stack().length()) { 662 if (ii < currentAccumulator.stack().length()) {
709 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); 663 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
710 } else { 664 } else {
711 cellText = "_"; 665 cellText = "_";
712 } 666 }
713 667
714 if (ii == (this.firstPoolReseedLevel() - 1)) { 668 if (ii == (this.firstPoolReseedLevel() - 1)) {
715 bdytd.style.borderRight = "1px solid lightgrey"; 669 bdytd.style.borderRight = "1px solid lightgrey";
716 } 670 }
717 671
718 bdytd.appendChild(document.createTextNode(cellText)); 672 bdytd.appendChild(document.createTextNode(cellText));
719 } 673 }
720 674
721 } 675 }
722 676
723 677
724 if (appendToDoc) { 678 if (appendToDoc) {
725 var ne = document.createElement("div"); 679 var ne = document.createElement("div");
726 ne.id = "entropyGeneratorStatus"; 680 ne.id = "entropyGeneratorStatus";
727 with (ne.style) { 681 with (ne.style) {
728 fontFamily = "Courier New, monospace"; 682 fontFamily = "Courier New, monospace";
729 fontSize = "12px"; 683 fontSize = "12px";
730 lineHeight = "16px"; 684 lineHeight = "16px";
731 borderTop = "1px solid black"; 685 borderTop = "1px solid black";
732 padding = "10px"; 686 padding = "10px";
733 } 687 }
734 if (document.getElementById(ne.id)) { 688 if (document.getElementById(ne.id)) {
735 MochiKit.DOM.swapDOM(ne.id, ne); 689 MochiKit.DOM.swapDOM(ne.id, ne);
736 } else { 690 } else {
737 document.body.appendChild(ne); 691 document.body.appendChild(ne);
738 } 692 }
739 ne.appendChild(tbl); 693 ne.appendChild(tbl);
740 } 694 }
741 695
742 return tbl; 696 return tbl;
743 }, 697 },
744 698*/
745 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
746 __syntaxFix__: "syntax fix" 700 __syntaxFix__: "syntax fix"
747}); 701});
748 702
749//############################################################################# 703//#############################################################################
750 704
751Clipperz.Crypto.PRNG.Random = function(args) { 705Clipperz.Crypto.PRNG.Random = function(args) {
752 args = args || {}; 706 args = args || {};
753 //MochiKit.Base.bindMethods(this); 707 //MochiKit.Base.bindMethods(this);
754 708
755 return this; 709 return this;
756} 710}
757 711
758Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { 712Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
759 713
760 'toString': function() { 714 'toString': function() {
761 return "Clipperz.Crypto.PRNG.Random"; 715 return "Clipperz.Crypto.PRNG.Random";
762 }, 716 },
763 717
764 //------------------------------------------------------------------------- 718 //-------------------------------------------------------------------------
765 719
766 'getRandomBytes': function(aSize) { 720 'getRandomBytes': function(aSize) {
767//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 721//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
768 varresult; 722 varresult;
769 var i,c; 723 var i,c;
770 724
771 result = new Clipperz.ByteArray() 725 result = new Clipperz.ByteArray()
772 c = aSize || 1; 726 c = aSize || 1;
773 for (i=0; i<c; i++) { 727 for (i=0; i<c; i++) {
774 result.appendByte((Math.random()*255) & 0xff); 728 result.appendByte((Math.random()*255) & 0xff);
775 } 729 }
776 730
777//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 731//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
778 return result; 732 return result;
779 }, 733 },
780 734
781 //------------------------------------------------------------------------- 735 //-------------------------------------------------------------------------
782 __syntaxFix__: "syntax fix" 736 __syntaxFix__: "syntax fix"
783}); 737});
784 738
785//############################################################################# 739//#############################################################################
786 740
787_clipperz_crypt_prng_defaultPRNG = null; 741var _clipperz_crypt_prng_defaultPRNG = null;
788 742
789Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { 743Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
790 if (_clipperz_crypt_prng_defaultPRNG == null) { 744 if (_clipperz_crypt_prng_defaultPRNG == null) {
791 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); 745 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
792 746
793 //............................................................. 747 //.............................................................
794 // 748 //
795 // TimeRandomnessSource 749 // TimeRandomnessSource
796 // 750 //
797 //............................................................. 751 //.............................................................
798 { 752 {
799 var newRandomnessSource; 753 var newRandomnessSource;
800 754
801 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); 755 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
802 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 756 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
803 } 757 }
804 758
805 //............................................................. 759 //.............................................................
806 // 760 //
807 // MouseRandomnessSource 761 // MouseRandomnessSource
808 // 762 //
809 //............................................................. 763 //.............................................................
810 { 764 {
811 varnewRandomnessSource; 765 varnewRandomnessSource;
812 766
813 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); 767 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
814 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 768 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
815 } 769 }
816 770
817 //............................................................. 771 //.............................................................
818 // 772 //
819 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
820 // 774 //
821 //............................................................. 775 //.............................................................
822 { 776 {
823 varnewRandomnessSource; 777 varnewRandomnessSource;
778 varbrowserCrypto;
824 779
825 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); 780 if (window.crypto && window.crypto.getRandomValues) {
826 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 781 browserCrypto = window.crypto;
782 } else if (window.msCrypto && window.msCrypto.getRandomValues) {
783 browserCrypto = window.msCrypto;
784 } else {
785 browserCrypto = null;
786 }
787
788 if (browserCrypto != null) {
789 newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto});
790 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
791 }
827 } 792 }
828
829 } 793 }
830 794
831 return _clipperz_crypt_prng_defaultPRNG; 795 return _clipperz_crypt_prng_defaultPRNG;
832}; 796};
833 797
834//############################################################################# 798//#############################################################################
835 799
836Clipperz.Crypto.PRNG.exception = { 800Clipperz.Crypto.PRNG.exception = {
837 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") 801 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
838}; 802};
839 803
840 804
841MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); 805MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);