Merge remote-tracking branch 'upstream/nightly' into nightly
This commit is contained in:
commit
1d39c9d66a
@ -65,7 +65,7 @@ class AddpeopletagAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -119,7 +119,7 @@ class AddpeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
// Throws exception on error
|
||||
$ptag = Profile_tag::setTag($this->user->id, $this->tagged->id,
|
||||
|
@ -54,7 +54,7 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -73,9 +73,9 @@ class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
|
@ -51,7 +51,7 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->user = $this->getTargetUser($this->arg('id'));
|
||||
@ -71,9 +71,9 @@ class ApiAtomServiceAction extends ApiBareAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
header('Content-Type: application/atomsvc+xml');
|
||||
|
||||
|
@ -58,7 +58,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -77,9 +77,9 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$sitename = common_config('site', 'name');
|
||||
// TRANS: Message is used as a title when listing the lastest 20 groups. %s is a site name.
|
||||
|
@ -33,7 +33,7 @@ class ApiListSubscriberAction extends ApiBareAuthAction
|
||||
{
|
||||
var $list = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -52,9 +52,9 @@ class ApiListSubscriberAction extends ApiBareAuthAction
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$arr = array('profile_tag_id' => $this->list->id,
|
||||
'profile_id' => $this->target->id);
|
||||
|
@ -52,9 +52,9 @@ class ApiOAuthAccessTokenAction extends ApiOAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$datastore = new ApiGNUsocialOAuthDataStore();
|
||||
$server = new OAuthServer($datastore);
|
||||
|
@ -60,7 +60,7 @@ class ApiOAuthAuthorizeAction extends ApiOAuthAction
|
||||
return false;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -88,9 +88,9 @@ class ApiOAuthAuthorizeAction extends ApiOAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
|
@ -49,7 +49,7 @@ class ApiOAuthRequestTokenAction extends ApiOAuthAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -69,9 +69,9 @@ class ApiOAuthRequestTokenAction extends ApiOAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$datastore = new ApiGNUsocialOAuthDataStore();
|
||||
$server = new OAuthServer($datastore);
|
||||
|
@ -88,7 +88,7 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -128,9 +128,9 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
common_debug("In apisearchatom handle()");
|
||||
$this->showAtom();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean true if nothing goes wrong
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -95,9 +95,9 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showResults();
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return boolean false if user doesn't exist
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
return true;
|
||||
@ -66,9 +66,9 @@ class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showTrends();
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class ApprovegroupAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -139,9 +139,9 @@ class ApprovegroupAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
try {
|
||||
if ($this->approve) {
|
||||
|
@ -50,7 +50,7 @@ class ApprovesubAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -97,9 +97,9 @@ class ApprovesubAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$cur = common_current_user();
|
||||
|
||||
try {
|
||||
|
@ -49,6 +49,20 @@ class AvatarsettingsAction extends SettingsAction
|
||||
var $imagefile = null;
|
||||
var $filename = null;
|
||||
|
||||
function prepare(array $args=array())
|
||||
{
|
||||
$avatarpath = Avatar::path('');
|
||||
|
||||
if (!is_writable($avatarpath)) {
|
||||
throw new Exception(_("The administrator of your site needs to
|
||||
add write permissions on the avatar upload folder before
|
||||
you're able to set one."));
|
||||
}
|
||||
|
||||
parent::prepare($args);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Title of the page
|
||||
*
|
||||
|
@ -53,7 +53,7 @@ class BlockAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
@ -78,7 +78,7 @@ class BlockAction extends ProfileFormAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
|
@ -50,7 +50,7 @@ class CancelgroupAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -127,9 +127,9 @@ class CancelgroupAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
try {
|
||||
$this->request->abort();
|
||||
|
@ -51,7 +51,7 @@ class DeleteapplicationAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
@ -89,7 +89,7 @@ class DeleteapplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
|
@ -55,7 +55,7 @@ class DeletegroupAction extends RedirectingAction
|
||||
* @fixme merge common setup code with other group actions
|
||||
* @fixme allow group admins to delete their own groups
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -114,9 +114,9 @@ class DeletegroupAction extends RedirectingAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToPrevious();
|
||||
|
@ -80,7 +80,7 @@ class DeleteuserAction extends ProfileFormAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
|
@ -57,7 +57,7 @@ class EditApplicationAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -94,9 +94,9 @@ class EditApplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->handlePost($args);
|
||||
|
@ -60,7 +60,7 @@ class EditpeopletagAction extends Action
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -135,9 +135,9 @@ class EditpeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->trySave();
|
||||
} else {
|
||||
|
@ -54,7 +54,7 @@ class FeaturedAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -74,9 +74,9 @@ class FeaturedAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$this->showPage();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class FoafGroupAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -76,9 +76,9 @@ class FoafGroupAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
header('Content-Type: application/rdf+xml');
|
||||
|
||||
|
@ -47,7 +47,7 @@ class GeocodeAction extends Action
|
||||
var $lon = null;
|
||||
var $location = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$token = $this->trimmed('token');
|
||||
@ -70,7 +70,7 @@ class GeocodeAction extends Action
|
||||
* @return nothing
|
||||
*
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
$location_object = array();
|
||||
|
@ -49,7 +49,7 @@ class GrantRoleAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -52,7 +52,7 @@ class GroupblockAction extends RedirectingAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
@ -110,9 +110,9 @@ class GroupblockAction extends RedirectingAction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToPrevious();
|
||||
|
@ -67,16 +67,16 @@ class GroupsAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class GroupunblockAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
@ -103,9 +103,9 @@ class GroupunblockAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->unblockProfile();
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ class InviteAction extends Action
|
||||
return false;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if (!common_config('invite', 'enabled')) {
|
||||
// TRANS: Client error displayed when trying to sent invites while they have been disabled.
|
||||
$this->clientError(_('Invites have been disabled.'));
|
||||
|
@ -54,7 +54,7 @@ class MakeadminAction extends RedirectingAction
|
||||
* @return boolean success flag
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
if (!common_logged_in()) {
|
||||
@ -111,9 +111,9 @@ class MakeadminAction extends RedirectingAction
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$this->makeAdmin();
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class NoticesearchAction extends SearchAction
|
||||
{
|
||||
protected $q = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
|
@ -55,9 +55,9 @@ class NudgeAction extends Action
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
|
@ -53,9 +53,9 @@ class OpensearchAction extends Action
|
||||
*
|
||||
* @return boolean false if user doesn't exist
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$type = $this->trimmed('type');
|
||||
$short_name = '';
|
||||
if ($type == 'people') {
|
||||
|
@ -53,7 +53,7 @@ class OtpAction extends Action
|
||||
var $returnto;
|
||||
var $lt;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -110,9 +110,9 @@ class OtpAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
// success!
|
||||
if (!common_set_user($this->user)) {
|
||||
|
@ -62,7 +62,7 @@ class PeopletagAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -84,9 +84,9 @@ class PeopletagAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class PeopletagautocompleteAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -112,7 +112,7 @@ class PeopletagautocompleteAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
//common_log(LOG_DEBUG, 'Autocomplete data: ' . json_encode($this->tags));
|
||||
if ($this->tags) {
|
||||
|
@ -53,7 +53,7 @@ class PeopletaggedAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -117,9 +117,9 @@ class PeopletaggedAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ class PeopletagsbyuserAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -135,9 +135,9 @@ class PeopletagsbyuserAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
# Post from the tag dropdown; redirect to a GET
|
||||
|
||||
|
@ -54,7 +54,7 @@ class PeopletagsforuserAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -95,9 +95,9 @@ class PeopletagsforuserAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class PeopletagsubscribersAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||
@ -117,9 +117,9 @@ class PeopletagsubscribersAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ class PeopletagsubscriptionsAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -97,9 +97,9 @@ class PeopletagsubscriptionsAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ class PluginEnableAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -121,7 +121,7 @@ class PluginEnableAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
$key = 'disable-' . $this->plugin;
|
||||
Config::save('plugins', $key, $this->overrideValue());
|
||||
|
@ -68,7 +68,7 @@ class ProfilecompletionAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -120,7 +120,7 @@ class ProfilecompletionAction extends Action
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
$this->msg = null;
|
||||
|
||||
|
@ -45,7 +45,7 @@ class ProfiletagbyidAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -83,7 +83,7 @@ class ProfiletagbyidAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
common_redirect($this->peopletag->homeUrl(), 303);
|
||||
}
|
||||
|
@ -92,9 +92,9 @@ class PublictagcloudAction extends Action
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,9 @@ class RecoverpasswordAction extends Action
|
||||
var $msg = null;
|
||||
var $success = null;
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if (common_logged_in()) {
|
||||
// TRANS: Client error displayed trying to recover password while already logged in.
|
||||
$this->clientError(_('You are already logged in!'));
|
||||
|
@ -63,7 +63,7 @@ class RedirectAction extends Action
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
common_redirect(common_local_url($this->arg('nextAction'), $this->arg('args')));
|
||||
}
|
||||
|
@ -120,9 +120,9 @@ class RegisterAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if (common_config('site', 'closed')) {
|
||||
// TRANS: Client error displayed when trying to register to a closed site.
|
||||
|
@ -66,7 +66,7 @@ class RemovepeopletagAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -120,7 +120,7 @@ class RemovepeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
// Throws exception on error
|
||||
|
||||
|
@ -49,7 +49,7 @@ class RevokeRoleAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -85,7 +85,7 @@ class RsdAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -126,7 +126,7 @@ class RsdAction extends Action
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
header('Content-Type: application/rsd+xml');
|
||||
|
||||
|
@ -49,7 +49,7 @@ class SandboxAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -65,7 +65,7 @@ class ShowApplicationAction extends Action
|
||||
*
|
||||
* @return success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -101,9 +101,9 @@ class ShowApplicationAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
|
@ -110,9 +110,7 @@ class SitenoticeadminpanelAction extends AdminPanelAction
|
||||
}
|
||||
|
||||
// scrub HTML input
|
||||
require_once INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php';
|
||||
$purifier = new HTMLPurifier();
|
||||
$siteNotice = $purifier->purify($siteNotice);
|
||||
$siteNotice = common_purify($siteNotice);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ class SubeditAction extends Action
|
||||
{
|
||||
var $profile = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -58,9 +58,9 @@ class SubeditAction extends Action
|
||||
return true;
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$cur = common_current_user();
|
||||
|
||||
|
@ -64,7 +64,7 @@ class SubscribeAction extends Action
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -118,7 +118,7 @@ class SubscribeAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
// Throws exception on error
|
||||
|
||||
|
@ -50,7 +50,7 @@ class SubscribepeopletagAction extends Action
|
||||
/**
|
||||
* Prepare to run
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -106,9 +106,9 @@ class SubscribepeopletagAction extends Action
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
|
@ -22,9 +22,9 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
// @todo FIXME: documentation needed.
|
||||
class SupAction extends Action
|
||||
{
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$seconds = $this->trimmed('seconds');
|
||||
|
||||
|
@ -44,7 +44,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
*/
|
||||
class UnblockAction extends ProfileFormAction
|
||||
{
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -49,7 +49,7 @@ class UnsandboxAction extends ProfileFormAction
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
if (!parent::prepare($args)) {
|
||||
return false;
|
||||
|
@ -44,9 +44,9 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
*/
|
||||
class UnsubscribeAction extends Action
|
||||
{
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
if (!common_logged_in()) {
|
||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
||||
$this->clientError(_('Not logged in.'));
|
||||
|
@ -51,7 +51,7 @@ class UnsubscribepeopletagAction extends Action
|
||||
* Prepare to run
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
function prepare(array $args = array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
@ -106,9 +106,9 @@ class UnsubscribepeopletagAction extends Action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
function handle()
|
||||
{
|
||||
parent::handle($args);
|
||||
parent::handle();
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
|
@ -248,10 +248,10 @@ class Notice extends Managed_DataObject
|
||||
return common_local_url('shownotice', array('notice' => $this->id), null, null, false);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
public function getTitle($imply=true)
|
||||
{
|
||||
$title = null;
|
||||
if (Event::handle('GetNoticeTitle', array($this, &$title))) {
|
||||
if (Event::handle('GetNoticeTitle', array($this, &$title)) && $imply) {
|
||||
// TRANS: Title of a notice posted without a title value.
|
||||
// TRANS: %1$s is a user name, %2$s is the notice creation date/time.
|
||||
$title = sprintf(_('%1$s\'s status on %2$s'),
|
||||
|
396
extlib/ParagonIE/ConstantTime/Base32.php
Normal file
396
extlib/ParagonIE/ConstantTime/Base32.php
Normal file
@ -0,0 +1,396 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base32
|
||||
* [A-Z][2-7]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base32 implements EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Decode a Base32-encoded string into raw binary
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*/
|
||||
public static function decode(string $src, bool $strictPadding = false): string
|
||||
{
|
||||
return static::doDecode($src, false, $strictPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an uppercase Base32-encoded string into raw binary
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*/
|
||||
public static function decodeUpper(string $src, bool $strictPadding = false): string
|
||||
{
|
||||
return static::doDecode($src, true, $strictPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into Base32 (RFC 4648)
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*/
|
||||
public static function encode(string $src): string
|
||||
{
|
||||
return static::doEncode($src, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into uppercase Base32 (RFC 4648)
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeUpper(string $src): string
|
||||
{
|
||||
return static::doEncode($src, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 96 && $src < 123) $ret += $src - 97 + 1; // -64
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96);
|
||||
|
||||
// if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
|
||||
$ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Uppercase variant.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5BitsUpper(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
|
||||
$ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* @param $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5Bits(int $src): string
|
||||
{
|
||||
$diff = 0x61;
|
||||
|
||||
// if ($src > 25) $ret -= 72;
|
||||
$diff -= ((25 - $src) >> 8) & 73;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* Uppercase variant.
|
||||
*
|
||||
* @param $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5BitsUpper(int $src): string
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $ret -= 40;
|
||||
$diff -= ((25 - $src) >> 8) & 41;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base32 decoding
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $upper
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
*/
|
||||
protected static function doDecode(string $src, bool $upper = false, bool $strictPadding = false): string
|
||||
{
|
||||
// We do this to reduce code duplication:
|
||||
$method = $upper
|
||||
? 'decode5BitsUpper'
|
||||
: 'decode5Bits';
|
||||
|
||||
// Remove padding
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 7) === 0) {
|
||||
for ($j = 0; $j < 7; ++$j) {
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 7) === 1) {
|
||||
throw new \RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$src = \rtrim($src, '=');
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
}
|
||||
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 8 <= $srcLen; $i += 8) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8));
|
||||
$c0 = static::$method($chunk[1]);
|
||||
$c1 = static::$method($chunk[2]);
|
||||
$c2 = static::$method($chunk[3]);
|
||||
$c3 = static::$method($chunk[4]);
|
||||
$c4 = static::$method($chunk[5]);
|
||||
$c5 = static::$method($chunk[6]);
|
||||
$c6 = static::$method($chunk[7]);
|
||||
$c7 = static::$method($chunk[8]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCCCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff,
|
||||
(($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff,
|
||||
(($c6 << 5) | ($c7 ) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
|
||||
$c0 = static::$method($chunk[1]);
|
||||
|
||||
if ($i + 6 < $srcLen) {
|
||||
$c1 = static::$method($chunk[2]);
|
||||
$c2 = static::$method($chunk[3]);
|
||||
$c3 = static::$method($chunk[4]);
|
||||
$c4 = static::$method($chunk[5]);
|
||||
$c5 = static::$method($chunk[6]);
|
||||
$c6 = static::$method($chunk[7]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff,
|
||||
(($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8;
|
||||
} elseif ($i + 5 < $srcLen) {
|
||||
$c1 = static::$method($chunk[2]);
|
||||
$c2 = static::$method($chunk[3]);
|
||||
$c3 = static::$method($chunk[4]);
|
||||
$c4 = static::$method($chunk[5]);
|
||||
$c5 = static::$method($chunk[6]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff,
|
||||
(($c4 << 7) | ($c5 << 2) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8;
|
||||
} elseif ($i + 4 < $srcLen) {
|
||||
$c1 = static::$method($chunk[2]);
|
||||
$c2 = static::$method($chunk[3]);
|
||||
$c3 = static::$method($chunk[4]);
|
||||
$c4 = static::$method($chunk[5]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8;
|
||||
} elseif ($i + 3 < $srcLen) {
|
||||
$c1 = static::$method($chunk[2]);
|
||||
$c2 = static::$method($chunk[3]);
|
||||
$c3 = static::$method($chunk[4]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
} elseif ($i + 2 < $srcLen) {
|
||||
$c1 = static::$method($chunk[2]);
|
||||
$c2 = static::$method($chunk[3]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$c1 = static::$method($chunk[2]);
|
||||
|
||||
$dest .= \pack(
|
||||
'C',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
} else {
|
||||
$dest .= \pack(
|
||||
'C',
|
||||
(($c0 << 3) ) & 0xff
|
||||
);
|
||||
$err |= ($c0) >> 8;
|
||||
}
|
||||
}
|
||||
if ($err !== 0) {
|
||||
throw new \RangeException(
|
||||
'Base32::doDecode() only expects characters in the correct base32 alphabet'
|
||||
);
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base32 Decoding
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $upper
|
||||
* @return string
|
||||
*/
|
||||
protected static function doEncode(string $src, bool $upper = false): string
|
||||
{
|
||||
// We do this to reduce code duplication:
|
||||
$method = $upper
|
||||
? 'encode5BitsUpper'
|
||||
: 'encode5Bits';
|
||||
|
||||
$dest = '';
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 5 <= $srcLen; $i += 5) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5));
|
||||
$b0 = $chunk[1];
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$b3 = $chunk[4];
|
||||
$b4 = $chunk[5];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
|
||||
static::$method((($b2 << 1) | ($b3 >> 7)) & 31) .
|
||||
static::$method((($b3 >> 2) ) & 31) .
|
||||
static::$method((($b3 << 3) | ($b4 >> 5)) & 31) .
|
||||
static::$method( $b4 & 31);
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 3 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$b3 = $chunk[4];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
|
||||
static::$method((($b2 << 1) | ($b3 >> 7)) & 31) .
|
||||
static::$method((($b3 >> 2) ) & 31) .
|
||||
static::$method((($b3 << 3) ) & 31) .
|
||||
'=';
|
||||
} elseif ($i + 2 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
|
||||
static::$method((($b2 << 1) ) & 31) .
|
||||
'===';
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) ) & 31) .
|
||||
'====';
|
||||
} else {
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method( ($b0 << 2) & 31) .
|
||||
'======';
|
||||
}
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
}
|
111
extlib/ParagonIE/ConstantTime/Base32Hex.php
Normal file
111
extlib/ParagonIE/ConstantTime/Base32Hex.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base32Hex
|
||||
* [0-9][A-V]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base32Hex extends Base32
|
||||
{
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86
|
||||
$ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5BitsUpper(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47);
|
||||
|
||||
// if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54
|
||||
$ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5Bits(int $src): string
|
||||
{
|
||||
$src += 0x30;
|
||||
|
||||
// if ($src > 0x39) $src += 0x61 - 0x3a; // 39
|
||||
$src += ((0x39 - $src) >> 8) & 39;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* Uppercase variant.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5BitsUpper(int $src): string
|
||||
{
|
||||
$src += 0x30;
|
||||
|
||||
// if ($src > 0x39) $src += 0x41 - 0x3a; // 7
|
||||
$src += ((0x39 - $src) >> 8) & 7;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
}
|
229
extlib/ParagonIE/ConstantTime/Base64.php
Normal file
229
extlib/ParagonIE/ConstantTime/Base64.php
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64
|
||||
* [A-Z][a-z][0-9]+/
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64 implements EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*/
|
||||
public static function encode(string $src): string
|
||||
{
|
||||
$dest = '';
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3));
|
||||
$b0 = $chunk[1];
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
|
||||
$dest .=
|
||||
static::encode6Bits( $b0 >> 2 ) .
|
||||
static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
|
||||
static::encode6Bits( $b2 & 63);
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$dest .=
|
||||
static::encode6Bits( $b0 >> 2 ) .
|
||||
static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
static::encode6Bits( ($b1 << 2) & 63) . '=';
|
||||
} else {
|
||||
$dest .=
|
||||
static::encode6Bits( $b0 >> 2) .
|
||||
static::encode6Bits(($b0 << 4) & 63) . '==';
|
||||
}
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* decode from base64 into binary
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $strictPadding
|
||||
* @return string|bool
|
||||
* @throws \RangeException
|
||||
*/
|
||||
public static function decode(string $src, bool $strictPadding = false): string
|
||||
{
|
||||
// Remove padding
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 3) === 0) {
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 3) === 1) {
|
||||
throw new \RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
throw new \RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$src = \rtrim($src, '=');
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
}
|
||||
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, 4));
|
||||
$c0 = static::decode6Bits($chunk[1]);
|
||||
$c1 = static::decode6Bits($chunk[2]);
|
||||
$c2 = static::decode6Bits($chunk[3]);
|
||||
$c3 = static::decode6Bits($chunk[4]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff),
|
||||
((($c2 << 6) | $c3 ) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
|
||||
$c0 = static::decode6Bits($chunk[1]);
|
||||
|
||||
if ($i + 2 < $srcLen) {
|
||||
$c1 = static::decode6Bits($chunk[2]);
|
||||
$c2 = static::decode6Bits($chunk[3]);
|
||||
$dest .= \pack(
|
||||
'CC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$c1 = static::decode6Bits($chunk[2]);
|
||||
$dest .= \pack(
|
||||
'C',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
} elseif ($i < $srcLen && $strictPadding) {
|
||||
$err |= 1;
|
||||
}
|
||||
}
|
||||
if ($err !== 0) {
|
||||
return false;
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] + /
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
|
||||
|
||||
// if ($src == 0x2b) $ret += 62 + 1;
|
||||
$ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63;
|
||||
|
||||
// if ($src == 0x2f) ret += 63 + 1;
|
||||
$ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += ((25 - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= ((51 - $src) >> 8) & 75;
|
||||
|
||||
// if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15
|
||||
$diff -= ((61 - $src) >> 8) & 15;
|
||||
|
||||
// if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3
|
||||
$diff += ((62 - $src) >> 8) & 3;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
}
|
88
extlib/ParagonIE/ConstantTime/Base64DotSlash.php
Normal file
88
extlib/ParagonIE/ConstantTime/Base64DotSlash.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64DotSlash
|
||||
* ./[A-Z][a-z][0-9]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64DotSlash extends Base64
|
||||
{
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* ./ [A-Z] [a-z] [0-9]
|
||||
* 0x2e-0x2f, 0x41-0x5a, 0x61-0x7a, 0x30-0x39
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45
|
||||
$ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45);
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$src += 0x2e;
|
||||
|
||||
// if ($src > 0x2f) $src += 0x41 - 0x30; // 17
|
||||
$src += ((0x2f - $src) >> 8) & 17;
|
||||
|
||||
// if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
|
||||
$src += ((0x5a - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 0x7a) $src += 0x30 - 0x7b; // -75
|
||||
$src -= ((0x7a - $src) >> 8) & 75;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
}
|
82
extlib/ParagonIE/ConstantTime/Base64DotSlashOrdered.php
Normal file
82
extlib/ParagonIE/ConstantTime/Base64DotSlashOrdered.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64DotSlashOrdered
|
||||
* ./[0-9][A-Z][a-z]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64DotSlashOrdered extends Base64
|
||||
{
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [.-9] [A-Z] [a-z]
|
||||
* 0x2e-0x39, 0x41-0x5a, 0x61-0x7a
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45
|
||||
$ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45);
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$src += 0x2e;
|
||||
|
||||
// if ($src > 0x39) $src += 0x41 - 0x3a; // 7
|
||||
$src += ((0x39 - $src) >> 8) & 7;
|
||||
|
||||
// if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
|
||||
$src += ((0x5a - $src) >> 8) & 6;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
}
|
95
extlib/ParagonIE/ConstantTime/Base64UrlSafe.php
Normal file
95
extlib/ParagonIE/ConstantTime/Base64UrlSafe.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64DotSlash
|
||||
* ./[A-Z][a-z][0-9]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64UrlSafe extends Base64
|
||||
{
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] - _
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2d, 0x5f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
|
||||
|
||||
// if ($src == 0x2c) $ret += 62 + 1;
|
||||
$ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63;
|
||||
|
||||
// if ($src == 0x5f) ret += 63 + 1;
|
||||
$ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += ((25 - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= ((51 - $src) >> 8) & 75;
|
||||
|
||||
// if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13
|
||||
$diff -= ((61 - $src) >> 8) & 13;
|
||||
|
||||
// if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3
|
||||
$diff += ((62 - $src) >> 8) & 49;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
}
|
98
extlib/ParagonIE/ConstantTime/Binary.php
Normal file
98
extlib/ParagonIE/ConstantTime/Binary.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Binary
|
||||
*
|
||||
* Binary string operators that don't choke on
|
||||
* mbstring.func_overload
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Binary
|
||||
{
|
||||
/**
|
||||
* Safe string length
|
||||
*
|
||||
* @ref mbstring.func_overload
|
||||
*
|
||||
* @param string $str
|
||||
* @return int
|
||||
*/
|
||||
public static function safeStrlen(string $str): int
|
||||
{
|
||||
if (\function_exists('mb_strlen')) {
|
||||
return \mb_strlen($str, '8bit');
|
||||
} else {
|
||||
return \strlen($str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe substring
|
||||
*
|
||||
* @ref mbstring.func_overload
|
||||
*
|
||||
* @staticvar boolean $exists
|
||||
* @param string $str
|
||||
* @param int $start
|
||||
* @param int $length
|
||||
* @return string
|
||||
* @throws \TypeError
|
||||
*/
|
||||
public static function safeSubstr(
|
||||
string $str,
|
||||
int $start = 0,
|
||||
$length = null
|
||||
): string {
|
||||
if (\function_exists('mb_substr')) {
|
||||
// mb_substr($str, 0, NULL, '8bit') returns an empty string on PHP
|
||||
// 5.3, so we have to find the length ourselves.
|
||||
if ($length === null) {
|
||||
if ($start >= 0) {
|
||||
$length = self::safeStrlen($str) - $start;
|
||||
} else {
|
||||
$length = -$start;
|
||||
}
|
||||
}
|
||||
// $length calculation above might result in a 0-length string
|
||||
if ($length === 0) {
|
||||
return '';
|
||||
}
|
||||
return \mb_substr($str, $start, $length, '8bit');
|
||||
}
|
||||
if ($length === 0) {
|
||||
return '';
|
||||
}
|
||||
// Unlike mb_substr(), substr() doesn't accept NULL for length
|
||||
if ($length !== null) {
|
||||
return \substr($str, $start, $length);
|
||||
} else {
|
||||
return \substr($str, $start);
|
||||
}
|
||||
}
|
||||
}
|
52
extlib/ParagonIE/ConstantTime/EncoderInterface.php
Normal file
52
extlib/ParagonIE/ConstantTime/EncoderInterface.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface EncoderInterface
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
interface EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $binString (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function encode(string $binString): string;
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $encodedString
|
||||
* @param bool $strictPadding Error on invalid padding
|
||||
* @return string (raw binary)
|
||||
*/
|
||||
public static function decode(string $encodedString, bool $strictPadding = false): string;
|
||||
}
|
245
extlib/ParagonIE/ConstantTime/Encoding.php
Normal file
245
extlib/ParagonIE/ConstantTime/Encoding.php
Normal file
@ -0,0 +1,245 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Encoding
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Encoding
|
||||
{
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32Encode(string $str): string
|
||||
{
|
||||
return Base32::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32EncodeUpper(string $str): string
|
||||
{
|
||||
return Base32::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 decoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32Decode(string $str): string
|
||||
{
|
||||
return Base32::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 decoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32DecodeUpper(string $str): string
|
||||
{
|
||||
return Base32::decodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32HexEncode(string $str): string
|
||||
{
|
||||
return Base32Hex::encode($str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32HexEncodeUpper(string $str): string
|
||||
{
|
||||
return Base32Hex::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 decoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32HexDecode(string $str): string
|
||||
{
|
||||
return Base32Hex::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 decoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base32HexDecodeUpper(string $str): string
|
||||
{
|
||||
return Base32Hex::decodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 encoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base64Encode(string $str): string
|
||||
{
|
||||
return Base64::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 decoding
|
||||
*
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base64Decode(string $str): string
|
||||
{
|
||||
return Base64::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
* @param $src
|
||||
* @return string
|
||||
*/
|
||||
public static function base64EncodeDotSlash(string $str): string
|
||||
{
|
||||
return Base64DotSlash::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode from base64 to raw binary
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param $src
|
||||
* @return bool|string
|
||||
* @throws \RangeException
|
||||
*/
|
||||
public static function base64DecodeDotSlash(string $str): string
|
||||
{
|
||||
return Base64DotSlash::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[.-9][A-Z][a-z]" or "./[0-9][A-Z][a-z]"
|
||||
* @param $src
|
||||
* @return string
|
||||
*/
|
||||
public static function base64EncodeDotSlashOrdered(string $str): string
|
||||
{
|
||||
return Base64DotSlashOrdered::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode from base64 to raw binary
|
||||
*
|
||||
* Base64 character set "[.-9][A-Z][a-z]" or "./[0-9][A-Z][a-z]"
|
||||
*
|
||||
* @param $src
|
||||
* @return bool|string
|
||||
* @throws \RangeException
|
||||
*/
|
||||
public static function base64DecodeDotSlashOrdered(string $str): string
|
||||
{
|
||||
return Base64DotSlashOrdered::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function hexEncode(string $bin_string): string
|
||||
{
|
||||
return Hex::encode($bin_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a hexadecimal string into a binary string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $hex_string
|
||||
* @return string (raw binary)
|
||||
* @throws \RangeException
|
||||
*/
|
||||
public static function hexDecode(string $hex_string): string
|
||||
{
|
||||
return Hex::decode($hex_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function hexEncodeUpper(string $bin_string): string
|
||||
{
|
||||
return Hex::encodeUpper($bin_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function hexDecodeUpper(string $bin_string): string
|
||||
{
|
||||
return Hex::decode($bin_string);
|
||||
}
|
||||
}
|
132
extlib/ParagonIE/ConstantTime/Hex.php
Normal file
132
extlib/ParagonIE/ConstantTime/Hex.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Hex
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Hex implements EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function encode(string $bin_string): string
|
||||
{
|
||||
$hex = '';
|
||||
$len = Binary::safeStrlen($bin_string);
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$chunk = \unpack('C', Binary::safeSubstr($bin_string, $i, 2));
|
||||
$c = $chunk[1] & 0xf;
|
||||
$b = $chunk[1] >> 4;
|
||||
$hex .= pack(
|
||||
'CC',
|
||||
(87 + $b + ((($b - 10) >> 8) & ~38)),
|
||||
(87 + $c + ((($c - 10) >> 8) & ~38))
|
||||
);
|
||||
}
|
||||
return $hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks, returning uppercase letters (as per RFC 4648)
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeUpper(string $bin_string): string
|
||||
{
|
||||
$hex = '';
|
||||
$len = Binary::safeStrlen($bin_string);
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$chunk = \unpack('C', Binary::safeSubstr($bin_string, $i, 2));
|
||||
$c = $chunk[1] & 0xf;
|
||||
$b = $chunk[1] >> 4;
|
||||
$hex .= pack(
|
||||
'CC',
|
||||
(55 + $b + ((($b - 10) >> 8) & ~6)),
|
||||
(55 + $c + ((($c - 10) >> 8) & ~6))
|
||||
);
|
||||
}
|
||||
return $hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a hexadecimal string into a binary string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $hex_string
|
||||
* @param bool $strictPadding
|
||||
* @return string (raw binary)
|
||||
* @throws \RangeException
|
||||
*/
|
||||
public static function decode(string $hexString, bool $strictPadding = false): string
|
||||
{
|
||||
$hex_pos = 0;
|
||||
$bin = '';
|
||||
$c_acc = 0;
|
||||
$hex_len = Binary::safeStrlen($hexString);
|
||||
$state = 0;
|
||||
if (($hex_len & 1) !== 0) {
|
||||
if ($strictPadding) {
|
||||
throw new \RangeException(
|
||||
'Expected an even number of hexadecimal characters'
|
||||
);
|
||||
} else {
|
||||
$hexString = '0' . $hexString;
|
||||
++$hex_len;
|
||||
}
|
||||
}
|
||||
|
||||
$chunk = \unpack('C*', $hexString);
|
||||
while ($hex_pos < $hex_len) {
|
||||
++$hex_pos;
|
||||
$c = $chunk[$hex_pos];
|
||||
$c_num = $c ^ 48;
|
||||
$c_num0 = ($c_num - 10) >> 8;
|
||||
$c_alpha = ($c & ~32) - 55;
|
||||
$c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
|
||||
if (($c_num0 | $c_alpha0) === 0) {
|
||||
throw new \RangeException(
|
||||
'hexEncode() only expects hexadecimal characters'
|
||||
);
|
||||
}
|
||||
$c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
|
||||
if ($state === 0) {
|
||||
$c_acc = $c_val * 16;
|
||||
} else {
|
||||
$bin .= \pack('C', $c_acc | $c_val);
|
||||
}
|
||||
$state ^= 1;
|
||||
}
|
||||
return $bin;
|
||||
}
|
||||
}
|
166
extlib/ParagonIE/ConstantTime/RFC4648.php
Normal file
166
extlib/ParagonIE/ConstantTime/RFC4648.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class RFC4648
|
||||
*
|
||||
* This class conforms strictly to the RFC
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class RFC4648
|
||||
{
|
||||
/**
|
||||
* RFC 4648 Base64 encoding
|
||||
*
|
||||
* "foo" -> "Zm9v"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base64Encode(string $str): string
|
||||
{
|
||||
return Base64::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 decoding
|
||||
*
|
||||
* "Zm9v" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base64Decode(string $str): string
|
||||
{
|
||||
return Base64::decode($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 (URL Safe) encoding
|
||||
*
|
||||
* "foo" -> "Zm9v"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base64UrlSafeEncode(string $str): string
|
||||
{
|
||||
return Base64UrlSafe::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 (URL Safe) decoding
|
||||
*
|
||||
* "Zm9v" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base64UrlSafeDecode(string $str): string
|
||||
{
|
||||
return Base64UrlSafe::decode($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* "foo" -> "MZXW6==="
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base32Encode(string $str): string
|
||||
{
|
||||
return Base32::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* "MZXW6===" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base32Decode(string $str): string
|
||||
{
|
||||
return Base32::decodeUpper($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32-Hex encoding
|
||||
*
|
||||
* "foo" -> "CPNMU==="
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base32HexEncode(string $str): string
|
||||
{
|
||||
return Base32::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32-Hex decoding
|
||||
*
|
||||
* "CPNMU===" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base32HexDecode(string $str): string
|
||||
{
|
||||
return Base32::decodeUpper($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base16 decoding
|
||||
*
|
||||
* "foo" -> "666F6F"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base16Encode(string $str): string
|
||||
{
|
||||
return Hex::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base16 decoding
|
||||
*
|
||||
* "666F6F" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public function base16Decode(string $str): string
|
||||
{
|
||||
return Hex::decode($str, true);
|
||||
}
|
||||
}
|
48
extlib/ParagonIE/LICENSE.txt
Normal file
48
extlib/ParagonIE/LICENSE.txt
Normal file
@ -0,0 +1,48 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Paragon Initiative Enterprises
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
This library was based on the work of Steve "Sc00bz" Thomas.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Steve Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
123
extlib/phpseclib/Crypt/AES.php
Normal file
123
extlib/phpseclib/Crypt/AES.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of AES.
|
||||
*
|
||||
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
|
||||
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
|
||||
* to save one include_once().
|
||||
*
|
||||
* If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
||||
* {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
|
||||
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
|
||||
* is called, again, at which point, it'll be recalculated.
|
||||
*
|
||||
* Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't
|
||||
* make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
|
||||
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $aes = new \phpseclib\Crypt\AES();
|
||||
*
|
||||
* $aes->setKey('abcdefghijklmnop');
|
||||
*
|
||||
* $size = 10 * 1024;
|
||||
* $plaintext = '';
|
||||
* for ($i = 0; $i < $size; $i++) {
|
||||
* $plaintext.= 'a';
|
||||
* }
|
||||
*
|
||||
* echo $aes->decrypt($aes->encrypt($plaintext));
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @category Crypt
|
||||
* @package AES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2008 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of AES.
|
||||
*
|
||||
* @package AES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class AES extends Rijndael
|
||||
{
|
||||
/**
|
||||
* Dummy function
|
||||
*
|
||||
* Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael::setBlockLength()
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \BadMethodCallException anytime it's called
|
||||
*/
|
||||
function setBlockLength($length)
|
||||
{
|
||||
throw new \BadMethodCallException('The block length cannot be set for AES.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael:setKeyLength()
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported');
|
||||
}
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Rijndael supports five different key lengths, AES only supports three.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael:setKey()
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Blowfish.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -15,9 +14,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/Blowfish.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $blowfish = new Crypt_Blowfish();
|
||||
* $blowfish = new \phpseclib\Crypt\Blowfish();
|
||||
*
|
||||
* $blowfish->setKey('12345678901234567890123456789012');
|
||||
*
|
||||
@ -27,139 +26,41 @@
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Crypt_Blowfish
|
||||
* @package Blowfish
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 1.0
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include Crypt_Base
|
||||
*
|
||||
* Base cipher class
|
||||
*/
|
||||
if (!class_exists('Crypt_Base')) {
|
||||
require_once('Base.php');
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see Crypt_Blowfish::encrypt()
|
||||
* @see Crypt_Blowfish::decrypt()
|
||||
*/
|
||||
/**
|
||||
* Encrypt / decrypt using the Counter mode.
|
||||
*
|
||||
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_CTR', CRYPT_MODE_CTR);
|
||||
/**
|
||||
* Encrypt / decrypt using the Electronic Code Book mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_ECB', CRYPT_MODE_ECB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Code Book Chaining mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_CBC', CRYPT_MODE_CBC);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see Crypt_Blowfish::Crypt_Blowfish()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Blowfish.
|
||||
*
|
||||
* @package Blowfish
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||
* @version 1.0
|
||||
* @access public
|
||||
* @package Crypt_Blowfish
|
||||
*/
|
||||
class Crypt_Blowfish extends Crypt_Base {
|
||||
class Blowfish extends Base
|
||||
{
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see Crypt_Base::block_size
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
*
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 56;
|
||||
|
||||
/**
|
||||
* The namespace used by the cipher for its constants.
|
||||
*
|
||||
* @see Crypt_Base::const_namespace
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $const_namespace = 'BLOWFISH';
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'blowfish';
|
||||
@ -167,8 +68,8 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
@ -176,12 +77,12 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
|
||||
*
|
||||
* S-Box 1
|
||||
* S-Box 0
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $sbox0 = array (
|
||||
var $sbox0 = array(
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
@ -342,7 +243,7 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* P-Array consists of 18 32-bit subkeys
|
||||
*
|
||||
* @var array $parray
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $parray = array(
|
||||
@ -356,7 +257,7 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
*
|
||||
* Holds the expanded key [p] and the key-depended s-boxes [sb]
|
||||
*
|
||||
* @var array $bctx
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $bctx;
|
||||
@ -364,72 +265,86 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* Holds the last used key
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
|
||||
* derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
||||
* of that, we'll just precompute it once.
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_ECB
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_CBC
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_CTR
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_CFB
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_OFB
|
||||
*
|
||||
* If not explictly set, CRYPT_BLOWFISH_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_Blowfish($mode = CRYPT_BLOWFISH_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
* Sets the key length.
|
||||
*
|
||||
* Keys can be of any length. Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
|
||||
* If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
|
||||
* with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
|
||||
*
|
||||
* If the key is more than 448-bits, we trim the excess bits.
|
||||
*
|
||||
* If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
|
||||
* Key lengths can be between 32 and 448 bits.
|
||||
*
|
||||
* @access public
|
||||
* @see Crypt_Base::setKey()
|
||||
* @param String $key
|
||||
* @param int $length
|
||||
*/
|
||||
function setKey($key)
|
||||
function setKeyLength($length)
|
||||
{
|
||||
$keylength = strlen($key);
|
||||
|
||||
if (!$keylength) {
|
||||
$key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
}
|
||||
elseif ($keylength > 56) {
|
||||
$key = substr($key, 0, 56);
|
||||
if ($length < 32 || $length > 448) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
$this->key_length = $length >> 3;
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::isValidEngine()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
if ($this->key_length != 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'bf-ecb';
|
||||
$this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -486,8 +401,8 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -522,8 +437,8 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -550,30 +465,28 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
}
|
||||
|
||||
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the performance-optimized function for de/encrypt()
|
||||
*
|
||||
* @see Crypt_Base::_setupInlineCrypt()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10);
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
|
||||
break;
|
||||
default:
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_Blowfish, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
@ -673,6 +586,3 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of DES.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -17,9 +16,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/DES.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $des = new Crypt_DES();
|
||||
* $des = new \phpseclib\Crypt\DES();
|
||||
*
|
||||
* $des->setKey('abcdefgh');
|
||||
*
|
||||
@ -33,170 +32,87 @@
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Crypt_DES
|
||||
* @package DES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include Crypt_Base
|
||||
*
|
||||
* Base cipher class
|
||||
*/
|
||||
if (!class_exists('Crypt_Base')) {
|
||||
require_once('Base.php');
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @see Crypt_DES::_processBlock()
|
||||
*/
|
||||
/**
|
||||
* Contains $keys[CRYPT_DES_ENCRYPT]
|
||||
*/
|
||||
define('CRYPT_DES_ENCRYPT', 0);
|
||||
/**
|
||||
* Contains $keys[CRYPT_DES_DECRYPT]
|
||||
*/
|
||||
define('CRYPT_DES_DECRYPT', 1);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see Crypt_DES::encrypt()
|
||||
* @see Crypt_DES::decrypt()
|
||||
*/
|
||||
/**
|
||||
* Encrypt / decrypt using the Counter mode.
|
||||
*
|
||||
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_CTR', CRYPT_MODE_CTR);
|
||||
/**
|
||||
* Encrypt / decrypt using the Electronic Code Book mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_ECB', CRYPT_MODE_ECB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Code Book Chaining mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_CBC', CRYPT_MODE_CBC);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_CFB', CRYPT_MODE_CFB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
||||
*/
|
||||
define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see Crypt_DES::Crypt_DES()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_DES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_DES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of DES.
|
||||
*
|
||||
* @package DES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.1.0
|
||||
* @access public
|
||||
* @package Crypt_DES
|
||||
*/
|
||||
class Crypt_DES extends Crypt_Base {
|
||||
class DES extends Base
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\DES::_setupKey()
|
||||
* @see \phpseclib\Crypt\DES::_processBlock()
|
||||
*/
|
||||
/**
|
||||
* Contains $keys[self::ENCRYPT]
|
||||
*/
|
||||
const ENCRYPT = 0;
|
||||
/**
|
||||
* Contains $keys[self::DECRYPT]
|
||||
*/
|
||||
const DECRYPT = 1;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see Crypt_Base::block_size
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
|
||||
/**
|
||||
* The Key
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see Crypt_Base::key
|
||||
* @see setKey()
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0\0\0\0\0\0\0\0";
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
*
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 8;
|
||||
|
||||
/**
|
||||
* The namespace used by the cipher for its constants.
|
||||
*
|
||||
* @see Crypt_Base::const_namespace
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $const_namespace = 'DES';
|
||||
var $key_length = 8;
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'des';
|
||||
|
||||
/**
|
||||
* The OpenSSL names of the cipher / modes
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::openssl_mode_names
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $openssl_mode_names = array(
|
||||
self::MODE_ECB => 'des-ecb',
|
||||
self::MODE_CBC => 'des-cbc',
|
||||
self::MODE_CFB => 'des-cfb',
|
||||
self::MODE_OFB => 'des-ofb'
|
||||
// self::MODE_CTR is undefined for DES
|
||||
);
|
||||
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
@ -204,11 +120,11 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Switch for DES/3DES encryption
|
||||
*
|
||||
* Used only if $engine == CRYPT_DES_MODE_INTERNAL
|
||||
* Used only if $engine == self::ENGINE_INTERNAL
|
||||
*
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @see Crypt_DES::_processBlock()
|
||||
* @var Integer
|
||||
* @see self::_setupKey()
|
||||
* @see self::_processBlock()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $des_rounds = 1;
|
||||
@ -216,17 +132,17 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* max possible size of $key
|
||||
*
|
||||
* @see Crypt_DES::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key_size_max = 8;
|
||||
var $key_length_max = 8;
|
||||
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $keys;
|
||||
@ -238,9 +154,9 @@ class Crypt_DES extends Crypt_Base {
|
||||
* with each byte containing all bits in the same state as the
|
||||
* corresponding bit in the index value.
|
||||
*
|
||||
* @see Crypt_DES::_processBlock()
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_processBlock()
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $shuffle = array(
|
||||
@ -379,7 +295,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
*
|
||||
* Indexing this table with each source byte performs the initial bit permutation.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $ipmap = array(
|
||||
@ -421,7 +337,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
* Inverse IP mapping helper table.
|
||||
* Indexing this table with a byte value reverses the bit order.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $invipmap = array(
|
||||
@ -465,7 +381,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
* Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
|
||||
* P table: concatenation can then be replaced by exclusive ORs.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox1 = array(
|
||||
@ -490,7 +406,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box2
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox2 = array(
|
||||
@ -515,7 +431,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box3
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox3 = array(
|
||||
@ -540,7 +456,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box4
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox4 = array(
|
||||
@ -565,7 +481,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box5
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox5 = array(
|
||||
@ -590,7 +506,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box6
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox6 = array(
|
||||
@ -615,7 +531,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box7
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox7 = array(
|
||||
@ -640,7 +556,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box8
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox8 = array(
|
||||
@ -665,52 +581,56 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_DES_MODE_ECB
|
||||
*
|
||||
* - CRYPT_DES_MODE_CBC
|
||||
*
|
||||
* - CRYPT_DES_MODE_CTR
|
||||
*
|
||||
* - CRYPT_DES_MODE_CFB
|
||||
*
|
||||
* - CRYPT_DES_MODE_OFB
|
||||
*
|
||||
* If not explictly set, CRYPT_DES_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::isValidEngine()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($this->key_length_max == 8) {
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
$this->cipher_name_openssl_ecb = 'des-ecb';
|
||||
$this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
|
||||
}
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
|
||||
* only use the first eight, if $key has more then eight characters in it, and pad $key with the
|
||||
* null byte if it is less then eight characters long.
|
||||
* Keys must be 64-bits long or 8 bytes long.
|
||||
*
|
||||
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed to be all zero's.
|
||||
*
|
||||
* @see Crypt_Base::setKey()
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @access public
|
||||
* @param String $key
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
// We check/cut here only up to max length of the key.
|
||||
// Key padding to the proper length will be done in _setupKey()
|
||||
if (strlen($key) > $this->key_size_max) {
|
||||
$key = substr($key, 0, $this->key_size_max);
|
||||
if (!($this instanceof TripleDES) && strlen($key) != 8) {
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported');
|
||||
}
|
||||
|
||||
// Sets the key
|
||||
@ -720,46 +640,46 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_encryptBlock()
|
||||
* @see Crypt_Base::encrypt()
|
||||
* @see Crypt_DES::encrypt()
|
||||
* @see \phpseclib\Crypt\Base::_encryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @see self::encrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
return $this->_processBlock($in, CRYPT_DES_ENCRYPT);
|
||||
return $this->_processBlock($in, self::ENCRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_decryptBlock()
|
||||
* @see Crypt_Base::decrypt()
|
||||
* @see Crypt_DES::decrypt()
|
||||
* @see \phpseclib\Crypt\Base::_decryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @see self::decrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
return $this->_processBlock($in, CRYPT_DES_DECRYPT);
|
||||
return $this->_processBlock($in, self::DECRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts a 64-bit block
|
||||
*
|
||||
* $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
|
||||
* $mode should be either self::ENCRYPT or self::DECRYPT. See
|
||||
* {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
|
||||
* idea of what this function does.
|
||||
*
|
||||
* @see Crypt_DES::_encryptBlock()
|
||||
* @see Crypt_DES::_decryptBlock()
|
||||
* @see self::_encryptBlock()
|
||||
* @see self::_decryptBlock()
|
||||
* @access private
|
||||
* @param String $block
|
||||
* @param Integer $mode
|
||||
* @return String
|
||||
* @param string $block
|
||||
* @param int $mode
|
||||
* @return string
|
||||
*/
|
||||
function _processBlock($block, $mode)
|
||||
{
|
||||
@ -839,7 +759,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Creates the key schedule
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -1320,8 +1240,8 @@ class Crypt_DES extends Crypt_Base {
|
||||
$d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
|
||||
|
||||
$keys[$des_round] = array(
|
||||
CRYPT_DES_ENCRYPT => array(),
|
||||
CRYPT_DES_DECRYPT => array_fill(0, 32, 0)
|
||||
self::ENCRYPT => array(),
|
||||
self::DECRYPT => array_fill(0, 32, 0)
|
||||
);
|
||||
for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
|
||||
$c <<= $shifts[$i];
|
||||
@ -1336,35 +1256,37 @@ class Crypt_DES extends Crypt_Base {
|
||||
$pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF];
|
||||
|
||||
// Reorder: odd bytes/even bytes. Push the result in key schedule.
|
||||
$keys[$des_round][CRYPT_DES_ENCRYPT][ ] =
|
||||
$keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
|
||||
$val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
|
||||
(($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
|
||||
$keys[$des_round][CRYPT_DES_ENCRYPT][ ] =
|
||||
$keys[$des_round][CRYPT_DES_DECRYPT][$ki ] = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
|
||||
$val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
|
||||
(($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
|
||||
$keys[$des_round][self::ENCRYPT][ ] = $val1;
|
||||
$keys[$des_round][self::DECRYPT][$ki - 1] = $val1;
|
||||
$keys[$des_round][self::ENCRYPT][ ] = $val2;
|
||||
$keys[$des_round][self::DECRYPT][$ki ] = $val2;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($this->des_rounds) {
|
||||
case 3: // 3DES keys
|
||||
$this->keys = array(
|
||||
CRYPT_DES_ENCRYPT => array_merge(
|
||||
$keys[0][CRYPT_DES_ENCRYPT],
|
||||
$keys[1][CRYPT_DES_DECRYPT],
|
||||
$keys[2][CRYPT_DES_ENCRYPT]
|
||||
self::ENCRYPT => array_merge(
|
||||
$keys[0][self::ENCRYPT],
|
||||
$keys[1][self::DECRYPT],
|
||||
$keys[2][self::ENCRYPT]
|
||||
),
|
||||
CRYPT_DES_DECRYPT => array_merge(
|
||||
$keys[2][CRYPT_DES_DECRYPT],
|
||||
$keys[1][CRYPT_DES_ENCRYPT],
|
||||
$keys[0][CRYPT_DES_DECRYPT]
|
||||
self::DECRYPT => array_merge(
|
||||
$keys[2][self::DECRYPT],
|
||||
$keys[1][self::ENCRYPT],
|
||||
$keys[0][self::DECRYPT]
|
||||
)
|
||||
);
|
||||
break;
|
||||
// case 1: // DES keys
|
||||
default:
|
||||
$this->keys = array(
|
||||
CRYPT_DES_ENCRYPT => $keys[0][CRYPT_DES_ENCRYPT],
|
||||
CRYPT_DES_DECRYPT => $keys[0][CRYPT_DES_DECRYPT]
|
||||
self::ENCRYPT => $keys[0][self::ENCRYPT],
|
||||
self::DECRYPT => $keys[0][self::DECRYPT]
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1372,12 +1294,12 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Setup the performance-optimized function for de/encrypt()
|
||||
*
|
||||
* @see Crypt_Base::_setupInlineCrypt()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& Crypt_DES::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// Engine configuration for:
|
||||
// - DES ($des_rounds == 1) or
|
||||
@ -1385,21 +1307,20 @@ class Crypt_DES extends Crypt_Base {
|
||||
$des_rounds = $this->des_rounds;
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
|
||||
// (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
|
||||
// Generation of a uniqe hash for our generated code
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
// For hi-optimized code, we create for each combination of
|
||||
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
|
||||
$code_hash = md5(str_pad("Crypt_DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key);
|
||||
break;
|
||||
default:
|
||||
// After max 10 hi-optimized functions, we create generic
|
||||
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
|
||||
// Currently 2 * 5 generic functions will be then max. possible.
|
||||
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// Is there a re-usable $lambda_functions in there? If not, we have to create it.
|
||||
@ -1429,8 +1350,8 @@ class Crypt_DES extends Crypt_Base {
|
||||
// No futher initialisation of the $keys schedule is necessary.
|
||||
// That is the extra performance boost.
|
||||
$k = array(
|
||||
CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT],
|
||||
CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT]
|
||||
self::ENCRYPT => $this->keys[self::ENCRYPT],
|
||||
self::DECRYPT => $this->keys[self::DECRYPT]
|
||||
);
|
||||
$init_encrypt = '';
|
||||
$init_decrypt = '';
|
||||
@ -1439,22 +1360,21 @@ class Crypt_DES extends Crypt_Base {
|
||||
// In generic optimized code mode, we have to use, as the best compromise [currently],
|
||||
// our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
|
||||
$k = array(
|
||||
CRYPT_DES_ENCRYPT => array(),
|
||||
CRYPT_DES_DECRYPT => array()
|
||||
self::ENCRYPT => array(),
|
||||
self::DECRYPT => array()
|
||||
);
|
||||
for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) {
|
||||
$k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']';
|
||||
$k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']';
|
||||
for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) {
|
||||
$k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
|
||||
$k[self::DECRYPT][$i] = '$kd[' . $i . ']';
|
||||
}
|
||||
$init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];';
|
||||
$init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];';
|
||||
$init_encrypt = '$ke = $self->keys[self::ENCRYPT];';
|
||||
$init_decrypt = '$kd = $self->keys[self::DECRYPT];';
|
||||
break;
|
||||
}
|
||||
|
||||
// Creating code for en- and decryption.
|
||||
$crypt_block = array();
|
||||
foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) {
|
||||
|
||||
foreach (array(self::ENCRYPT, self::DECRYPT) as $c) {
|
||||
/* Do the initial IP permutation. */
|
||||
$crypt_block[$c] = '
|
||||
$in = unpack("N*", $in);
|
||||
@ -1521,8 +1441,8 @@ class Crypt_DES extends Crypt_Base {
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => $init_encrypt,
|
||||
'init_decrypt' => $init_decrypt,
|
||||
'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT],
|
||||
'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT]
|
||||
'encrypt_block' => $crypt_block[self::ENCRYPT],
|
||||
'decrypt_block' => $crypt_block[self::DECRYPT]
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -1531,6 +1451,3 @@ class Crypt_DES extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
463
extlib/phpseclib/Crypt/Hash.php
Normal file
463
extlib/phpseclib/Crypt/Hash.php
Normal file
@ -0,0 +1,463 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper around hash() and hash_hmac() functions supporting truncated hashes
|
||||
* such as sha256-96. Any hash algorithm returned by hash_algos() (and
|
||||
* truncated versions thereof) are supported.
|
||||
*
|
||||
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will
|
||||
* return the HMAC as opposed to the hash.
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $hash = new \phpseclib\Crypt\Hash('sha512');
|
||||
*
|
||||
* $hash->setKey('abcdefg');
|
||||
*
|
||||
* echo base64_encode($hash->hash('abcdefg'));
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Hash
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2015 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Math\BigInteger;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
|
||||
/**
|
||||
* @package Hash
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @access public
|
||||
*/
|
||||
class Hash
|
||||
{
|
||||
/**
|
||||
* Hash Parameter
|
||||
*
|
||||
* @see self::setHash()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $hashParam;
|
||||
|
||||
/**
|
||||
* Byte-length of hash output (Internal HMAC)
|
||||
*
|
||||
* @see self::setHash()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $length;
|
||||
|
||||
/**
|
||||
* Hash Algorithm
|
||||
*
|
||||
* @see self::setHash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $hash;
|
||||
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = false;
|
||||
|
||||
/**
|
||||
* Initial Hash
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::_sha512()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $initial = false;
|
||||
|
||||
/**
|
||||
* Outer XOR (Internal HMAC)
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $opad;
|
||||
|
||||
/**
|
||||
* Inner XOR (Internal HMAC)
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $ipad;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param string $hash
|
||||
* @access public
|
||||
*/
|
||||
function __construct($hash = 'sha256')
|
||||
{
|
||||
$this->setHash($hash);
|
||||
|
||||
$this->ipad = str_repeat(chr(0x36), 128);
|
||||
$this->opad = str_repeat(chr(0x5C), 128);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key for HMACs
|
||||
*
|
||||
* Keys can be of any length.
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key = false)
|
||||
{
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hash function.
|
||||
*
|
||||
* As set by the constructor or by the setHash() method.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getHash()
|
||||
{
|
||||
return $this->hashParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hash function.
|
||||
*
|
||||
* @access public
|
||||
* @param string $hash
|
||||
*/
|
||||
function setHash($hash)
|
||||
{
|
||||
$this->hashParam = $hash = strtolower($hash);
|
||||
switch ($hash) {
|
||||
case 'md2-96':
|
||||
case 'md5-96':
|
||||
case 'sha1-96':
|
||||
case 'sha256-96':
|
||||
case 'sha512-96':
|
||||
case 'sha512/224-96':
|
||||
case 'sha512/256-96':
|
||||
$hash = substr($hash, 0, -3);
|
||||
$this->length = 12; // 96 / 8 = 12
|
||||
break;
|
||||
case 'md2':
|
||||
case 'md5':
|
||||
$this->length = 16;
|
||||
break;
|
||||
case 'sha1':
|
||||
$this->length = 20;
|
||||
break;
|
||||
case 'sha224':
|
||||
case 'sha512/224':
|
||||
$this->length = 28;
|
||||
break;
|
||||
case 'sha256':
|
||||
case 'sha512/256':
|
||||
$this->length = 32;
|
||||
break;
|
||||
case 'sha384':
|
||||
$this->length = 48;
|
||||
break;
|
||||
case 'sha512':
|
||||
$this->length = 64;
|
||||
break;
|
||||
default:
|
||||
// see if the hash isn't "officially" supported see if it can
|
||||
// be "unofficially" supported and calculate the length
|
||||
// accordingly.
|
||||
if (in_array($hash, hash_algos())) {
|
||||
$this->length = strlen(hash($hash, '', true));
|
||||
break;
|
||||
}
|
||||
// if the hash algorithm doens't exist maybe it's a truncated
|
||||
// hash, e.g. whirlpool-12 or some such.
|
||||
if (preg_match('#(-\d+)$#', $hash, $matches)) {
|
||||
$hash = substr($hash, 0, -strlen($matches[1]));
|
||||
if (in_array($hash, hash_algos())) {
|
||||
$this->length = abs($matches[1]) >> 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedAlgorithmException(
|
||||
"$hash is not a supported algorithm"
|
||||
);
|
||||
}
|
||||
|
||||
if ($hash == 'sha512/224' || $hash == 'sha512/256') {
|
||||
// from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24
|
||||
$this->initial = $hash == 'sha512/256' ?
|
||||
array(
|
||||
'22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD',
|
||||
'96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2'
|
||||
) :
|
||||
array(
|
||||
'8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF',
|
||||
'0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1'
|
||||
);
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$this->initial[$i] = new BigInteger($this->initial[$i], 16);
|
||||
$this->initial[$i]->setPrecision(64);
|
||||
}
|
||||
}
|
||||
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the HMAC.
|
||||
*
|
||||
* @access public
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function hash($text)
|
||||
{
|
||||
switch ($this->hash) {
|
||||
case 'sha512/224':
|
||||
case 'sha512/256':
|
||||
if (empty($this->key) || !is_string($this->key)) {
|
||||
return substr(self::_sha512($text, $this->initial), 0, $this->length);
|
||||
}
|
||||
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
||||
resultant L byte string as the actual key to HMAC."
|
||||
|
||||
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
||||
$key = strlen($this->key) > $this->b ? self::_sha512($this->key, $this->initial) : $this->key;
|
||||
|
||||
$key = str_pad($this->key, 128, chr(0)); // step 1
|
||||
$temp = $this->ipad ^ $this->key; // step 2
|
||||
$temp .= $text; // step 3
|
||||
$temp = self::_sha512($temp, $this->initial); // step 4
|
||||
$output = $this->opad ^ $this->key; // step 5
|
||||
$output.= $temp; // step 6
|
||||
$output = self::_sha512($output, $this->initial); // step 7
|
||||
|
||||
return substr($output, 0, $this->length);
|
||||
}
|
||||
$output = !empty($this->key) || is_string($this->key) ?
|
||||
hash_hmac($this->hash, $text, $this->key, true) :
|
||||
hash($this->hash, $text, true);
|
||||
|
||||
return strlen($output) > $this->length
|
||||
? substr($output, 0, $this->length)
|
||||
: $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash length (in bytes)
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getLength()
|
||||
{
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of SHA512
|
||||
*
|
||||
* @access private
|
||||
* @param string $m
|
||||
*/
|
||||
static function _sha512($m, $hash)
|
||||
{
|
||||
static $k;
|
||||
|
||||
if (!isset($k)) {
|
||||
// Initialize table of round constants
|
||||
// (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
|
||||
$k = array(
|
||||
'428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
|
||||
'3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
|
||||
'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
|
||||
'72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
|
||||
'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
|
||||
'2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
|
||||
'983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
|
||||
'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
|
||||
'27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
|
||||
'650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
|
||||
'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
|
||||
'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
|
||||
'19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
|
||||
'391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
|
||||
'748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
|
||||
'90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
|
||||
'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
|
||||
'06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
|
||||
'28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
|
||||
'4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
|
||||
);
|
||||
|
||||
for ($i = 0; $i < 80; $i++) {
|
||||
$k[$i] = new BigInteger($k[$i], 16);
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-processing
|
||||
$length = strlen($m);
|
||||
// to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
|
||||
$m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
|
||||
$m[$length] = chr(0x80);
|
||||
// we don't support hashing strings 512MB long
|
||||
$m.= pack('N4', 0, 0, 0, $length << 3);
|
||||
|
||||
// Process the message in successive 1024-bit chunks
|
||||
$chunks = str_split($m, 128);
|
||||
foreach ($chunks as $chunk) {
|
||||
$w = array();
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$temp = new BigInteger(self::_string_shift($chunk, 8), 256);
|
||||
$temp->setPrecision(64);
|
||||
$w[] = $temp;
|
||||
}
|
||||
|
||||
// Extend the sixteen 32-bit words into eighty 32-bit words
|
||||
for ($i = 16; $i < 80; $i++) {
|
||||
$temp = array(
|
||||
$w[$i - 15]->bitwise_rightRotate(1),
|
||||
$w[$i - 15]->bitwise_rightRotate(8),
|
||||
$w[$i - 15]->bitwise_rightShift(7)
|
||||
);
|
||||
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
||||
$s0 = $s0->bitwise_xor($temp[2]);
|
||||
$temp = array(
|
||||
$w[$i - 2]->bitwise_rightRotate(19),
|
||||
$w[$i - 2]->bitwise_rightRotate(61),
|
||||
$w[$i - 2]->bitwise_rightShift(6)
|
||||
);
|
||||
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
||||
$s1 = $s1->bitwise_xor($temp[2]);
|
||||
$w[$i] = clone $w[$i - 16];
|
||||
$w[$i] = $w[$i]->add($s0);
|
||||
$w[$i] = $w[$i]->add($w[$i - 7]);
|
||||
$w[$i] = $w[$i]->add($s1);
|
||||
}
|
||||
|
||||
// Initialize hash value for this chunk
|
||||
$a = clone $hash[0];
|
||||
$b = clone $hash[1];
|
||||
$c = clone $hash[2];
|
||||
$d = clone $hash[3];
|
||||
$e = clone $hash[4];
|
||||
$f = clone $hash[5];
|
||||
$g = clone $hash[6];
|
||||
$h = clone $hash[7];
|
||||
|
||||
// Main loop
|
||||
for ($i = 0; $i < 80; $i++) {
|
||||
$temp = array(
|
||||
$a->bitwise_rightRotate(28),
|
||||
$a->bitwise_rightRotate(34),
|
||||
$a->bitwise_rightRotate(39)
|
||||
);
|
||||
$s0 = $temp[0]->bitwise_xor($temp[1]);
|
||||
$s0 = $s0->bitwise_xor($temp[2]);
|
||||
$temp = array(
|
||||
$a->bitwise_and($b),
|
||||
$a->bitwise_and($c),
|
||||
$b->bitwise_and($c)
|
||||
);
|
||||
$maj = $temp[0]->bitwise_xor($temp[1]);
|
||||
$maj = $maj->bitwise_xor($temp[2]);
|
||||
$t2 = $s0->add($maj);
|
||||
|
||||
$temp = array(
|
||||
$e->bitwise_rightRotate(14),
|
||||
$e->bitwise_rightRotate(18),
|
||||
$e->bitwise_rightRotate(41)
|
||||
);
|
||||
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
||||
$s1 = $s1->bitwise_xor($temp[2]);
|
||||
$temp = array(
|
||||
$e->bitwise_and($f),
|
||||
$g->bitwise_and($e->bitwise_not())
|
||||
);
|
||||
$ch = $temp[0]->bitwise_xor($temp[1]);
|
||||
$t1 = $h->add($s1);
|
||||
$t1 = $t1->add($ch);
|
||||
$t1 = $t1->add($k[$i]);
|
||||
$t1 = $t1->add($w[$i]);
|
||||
|
||||
$h = clone $g;
|
||||
$g = clone $f;
|
||||
$f = clone $e;
|
||||
$e = $d->add($t1);
|
||||
$d = clone $c;
|
||||
$c = clone $b;
|
||||
$b = clone $a;
|
||||
$a = $t1->add($t2);
|
||||
}
|
||||
|
||||
// Add this chunk's hash to result so far
|
||||
$hash = array(
|
||||
$hash[0]->add($a),
|
||||
$hash[1]->add($b),
|
||||
$hash[2]->add($c),
|
||||
$hash[3]->add($d),
|
||||
$hash[4]->add($e),
|
||||
$hash[5]->add($f),
|
||||
$hash[6]->add($g),
|
||||
$hash[7]->add($h)
|
||||
);
|
||||
}
|
||||
|
||||
// Produce the final hash value (big-endian)
|
||||
// (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
|
||||
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
|
||||
$hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes();
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC2.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -15,9 +14,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/RC2.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $rc2 = new Crypt_RC2();
|
||||
* $rc2 = new \phpseclib\Crypt\RC2();
|
||||
*
|
||||
* $rc2->setKey('abcdefgh');
|
||||
*
|
||||
@ -27,106 +26,28 @@
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Crypt_RC2
|
||||
* @package RC2
|
||||
* @author Patrick Monnerat <pm@datasphere.ch>
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include Crypt_Base
|
||||
*
|
||||
* Base cipher class
|
||||
*/
|
||||
if (!class_exists('Crypt_Base')) {
|
||||
require_once('Base.php');
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see Crypt_RC2::encrypt()
|
||||
* @see Crypt_RC2::decrypt()
|
||||
*/
|
||||
/**
|
||||
* Encrypt / decrypt using the Counter mode.
|
||||
*
|
||||
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
||||
*/
|
||||
define('CRYPT_RC2_MODE_CTR', CRYPT_MODE_CTR);
|
||||
/**
|
||||
* Encrypt / decrypt using the Electronic Code Book mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
||||
*/
|
||||
define('CRYPT_RC2_MODE_ECB', CRYPT_MODE_ECB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Code Book Chaining mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
*/
|
||||
define('CRYPT_RC2_MODE_CBC', CRYPT_MODE_CBC);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
||||
*/
|
||||
define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see Crypt_RC2::Crypt_RC2()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_RC2_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_RC2_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC2.
|
||||
*
|
||||
* @version 0.1.1
|
||||
* @package RC2
|
||||
* @access public
|
||||
* @package Crypt_RC2
|
||||
*/
|
||||
class Crypt_RC2 extends Crypt_Base {
|
||||
class RC2 extends Base
|
||||
{
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see Crypt_Base::block_size
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
@ -134,37 +55,48 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* The Key
|
||||
*
|
||||
* @see Crypt_Base::key
|
||||
* @see setKey()
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::key
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0";
|
||||
var $key;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* The Original (unpadded) Key
|
||||
*
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::key
|
||||
* @see self::setKey()
|
||||
* @see self::encrypt()
|
||||
* @see self::decrypt()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 16; // = 128 bits
|
||||
var $orig_key;
|
||||
|
||||
/**
|
||||
* The namespace used by the cipher for its constants.
|
||||
* Don't truncate / null pad key
|
||||
*
|
||||
* @see Crypt_Base::const_namespace
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::_clearBuffers()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $const_namespace = 'RC2';
|
||||
var $skip_key_adjustment = true;
|
||||
|
||||
/**
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key_length = 16; // = 128 bits
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'rc2';
|
||||
@ -172,29 +104,40 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
|
||||
/**
|
||||
/**
|
||||
* The key length in bits.
|
||||
*
|
||||
* @see Crypt_RC2::setKeyLength()
|
||||
* @see Crypt_RC2::setKey()
|
||||
* @var Integer
|
||||
* @see self::setKeyLength()
|
||||
* @see self::setKey()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal Should be in range [1..1024].
|
||||
* @internal Changing this value after setting the key has no effect.
|
||||
*/
|
||||
var $default_key_length = 1024;
|
||||
|
||||
/**
|
||||
* The key length in bits.
|
||||
*
|
||||
* @see self::isValidEnine()
|
||||
* @see self::setKey()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal Should be in range [1..1024].
|
||||
*/
|
||||
var $current_key_length;
|
||||
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see Crypt_RC2::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $keys;
|
||||
@ -203,8 +146,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
* Key expansion randomization table.
|
||||
* Twice the same 256-value sequence to save a modulus in key expansion.
|
||||
*
|
||||
* @see Crypt_RC2::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $pitable = array(
|
||||
@ -277,8 +220,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Inverse key expansion randomization table.
|
||||
*
|
||||
* @see Crypt_RC2::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $invpitable = array(
|
||||
@ -319,53 +262,78 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_RC2_MODE_ECB
|
||||
*
|
||||
* - CRYPT_RC2_MODE_CBC
|
||||
*
|
||||
* - CRYPT_RC2_MODE_CTR
|
||||
*
|
||||
* - CRYPT_RC2_MODE_CFB
|
||||
*
|
||||
* - CRYPT_RC2_MODE_OFB
|
||||
*
|
||||
* If not explictly set, CRYPT_RC2_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_RC2($mode = CRYPT_RC2_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
$this->setKey('');
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
* Test for engine validity
|
||||
*
|
||||
* Valid key lengths are 1 to 1024.
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
switch ($engine) {
|
||||
case self::ENGINE_OPENSSL:
|
||||
if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'rc2-ecb';
|
||||
$this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode();
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 8 to 1024.
|
||||
* Calling this function after setting the key has no effect until the next
|
||||
* Crypt_RC2::setKey() call.
|
||||
* \phpseclib\Crypt\RC2::setKey() call.
|
||||
*
|
||||
* @access public
|
||||
* @param Integer $length in bits
|
||||
* @param int $length in bits
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length >= 1 && $length <= 1024) {
|
||||
$this->default_key_length = $length;
|
||||
if ($length < 8 || $length > 1024) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
|
||||
}
|
||||
|
||||
$this->default_key_length = $this->current_key_length = $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current key length
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getKeyLength()
|
||||
{
|
||||
return $this->current_key_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. RC2, itself, uses 1 to 1024 bit keys (eg.
|
||||
* Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
|
||||
* strlen($key) <= 128), however, we only use the first 128 bytes if $key
|
||||
* has more then 128 bytes in it, and set $key to a single null byte if
|
||||
* it is empty.
|
||||
@ -373,20 +341,27 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
* If the key is not explicitly set, it'll be assumed to be a single
|
||||
* null byte.
|
||||
*
|
||||
* @see Crypt_Base::setKey()
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @access public
|
||||
* @param String $key
|
||||
* @param Integer $t1 optional Effective key length in bits.
|
||||
* @param string $key
|
||||
* @param int $t1 optional Effective key length in bits.
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key, $t1 = 0)
|
||||
function setKey($key, $t1 = false)
|
||||
{
|
||||
if ($t1 <= 0) {
|
||||
$this->orig_key = $key;
|
||||
|
||||
if ($t1 === false) {
|
||||
$t1 = $this->default_key_length;
|
||||
} else if ($t1 > 1024) {
|
||||
$t1 = 1024;
|
||||
}
|
||||
|
||||
if ($t1 < 1 || $t1 > 1024) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
|
||||
}
|
||||
|
||||
$this->current_key_length = $t1;
|
||||
// Key byte count should be 1..128.
|
||||
$key = strlen($key) ? substr($key, 0, 128): "\x00";
|
||||
$key = strlen($key) ? substr($key, 0, 128) : "\x00";
|
||||
$t = strlen($key);
|
||||
|
||||
// The mcrypt RC2 implementation only supports effective key length
|
||||
@ -414,17 +389,64 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
// Prepare the key for mcrypt.
|
||||
$l[0] = $this->invpitable[$l[0]];
|
||||
array_unshift($l, 'C*');
|
||||
|
||||
parent::setKey(call_user_func_array('pack', $l));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code
|
||||
*
|
||||
* @see self::decrypt()
|
||||
* @access public
|
||||
* @param string $plaintext
|
||||
* @return string $ciphertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
if ($this->engine == self::ENGINE_OPENSSL) {
|
||||
$temp = $this->key;
|
||||
$this->key = $this->orig_key;
|
||||
$result = parent::encrypt($plaintext);
|
||||
$this->key = $temp;
|
||||
return $result;
|
||||
}
|
||||
|
||||
return parent::encrypt($plaintext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a message.
|
||||
*
|
||||
* Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code
|
||||
*
|
||||
* @see self::encrypt()
|
||||
* @access public
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->engine == self::ENGINE_OPENSSL) {
|
||||
$temp = $this->key;
|
||||
$this->key = $this->orig_key;
|
||||
$result = parent::decrypt($ciphertext);
|
||||
$this->key = $temp;
|
||||
return $result;
|
||||
}
|
||||
|
||||
return parent::decrypt($ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_encryptBlock()
|
||||
* @see Crypt_Base::encrypt()
|
||||
* @see \phpseclib\Crypt\Base::_encryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -445,8 +467,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
|
||||
$r3 |= $r3 >> 16;
|
||||
|
||||
if ($j == $limit) {
|
||||
if ($limit == 64) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -465,11 +487,11 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_decryptBlock()
|
||||
* @see Crypt_Base::decrypt()
|
||||
* @see \phpseclib\Crypt\Base::_decryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -490,8 +512,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$r0 = ($r0 | ($r0 << 16)) >> 1;
|
||||
$r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
|
||||
|
||||
if ($j == $limit) {
|
||||
if (!$limit) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -507,15 +529,34 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
return pack('vvvv', $r0, $r1, $r2, $r3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_setupMcrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupMcrypt()
|
||||
{
|
||||
if (!isset($this->key)) {
|
||||
$this->setKey('');
|
||||
}
|
||||
|
||||
parent::_setupMcrypt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the key schedule
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
{
|
||||
// Key has already been expanded in Crypt_RC2::setKey():
|
||||
if (!isset($this->key)) {
|
||||
$this->setKey('');
|
||||
}
|
||||
|
||||
// Key has already been expanded in \phpseclib\Crypt\RC2::setKey():
|
||||
// Only the first value must be altered.
|
||||
$l = unpack('Ca/Cb/v*', $this->key);
|
||||
array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
|
||||
@ -527,24 +568,24 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Setup the performance-optimized function for de/encrypt()
|
||||
*
|
||||
* @see Crypt_Base::_setupInlineCrypt()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions = &Crypt_RC2::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// The first 10 generated $lambda_functions will use the $keys hardcoded as integers
|
||||
// for the mixing rounds, for better inline crypt performance [~20% faster].
|
||||
// But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
|
||||
$keys = $this->keys;
|
||||
if (count($lambda_functions) >= 10) {
|
||||
foreach ($this->keys as $k => $v) {
|
||||
$keys[$k] = '$keys[' . $k . ']';
|
||||
}
|
||||
}
|
||||
// (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
$code_hash = md5(str_pad("Crypt_RC2, {$this->mode}, ", 32, "\0") . implode(',', $keys));
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_RC2, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// Is there a re-usable $lambda_functions in there?
|
||||
// If not, we have to create it.
|
||||
@ -552,6 +593,16 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
// Init code for both, encrypt and decrypt.
|
||||
$init_crypt = '$keys = $self->keys;';
|
||||
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$keys = $this->keys;
|
||||
default:
|
||||
$keys = array();
|
||||
foreach ($this->keys as $k => $v) {
|
||||
$keys[$k] = '$keys[' . $k . ']';
|
||||
}
|
||||
}
|
||||
|
||||
// $in is the current 8 bytes block which has to be en/decrypt
|
||||
$encrypt_block = $decrypt_block = '
|
||||
$in = unpack("v4", $in);
|
||||
@ -582,8 +633,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
|
||||
$r3 |= $r3 >> 16;';
|
||||
|
||||
if ($j == $limit) {
|
||||
if ($limit == 64) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -620,8 +671,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$r0 = ($r0 - ' . $keys[--$j] . ' -
|
||||
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
|
||||
|
||||
if ($j == $limit) {
|
||||
if (!$limit) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -651,6 +702,3 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
343
extlib/phpseclib/Crypt/RC4.php
Normal file
343
extlib/phpseclib/Crypt/RC4.php
Normal file
@ -0,0 +1,343 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC4.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
* - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
|
||||
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
|
||||
*
|
||||
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
|
||||
* ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $rc4 = new \phpseclib\Crypt\RC4();
|
||||
*
|
||||
* $rc4->setKey('abcdefgh');
|
||||
*
|
||||
* $size = 10 * 1024;
|
||||
* $plaintext = '';
|
||||
* for ($i = 0; $i < $size; $i++) {
|
||||
* $plaintext.= 'a';
|
||||
* }
|
||||
*
|
||||
* echo $rc4->decrypt($rc4->encrypt($plaintext));
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RC4
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC4.
|
||||
*
|
||||
* @package RC4
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class RC4 extends Base
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\RC4::_crypt()
|
||||
*/
|
||||
const ENCRYPT = 0;
|
||||
const DECRYPT = 1;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* RC4 is a stream cipher
|
||||
* so we the block_size to 0
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 0;
|
||||
|
||||
/**
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC4::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key_length = 128; // = 1024 bits
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'arcfour';
|
||||
|
||||
/**
|
||||
* Holds whether performance-optimized $inline_crypt() can/should be used.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::inline_crypt
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $use_inline_crypt = false; // currently not available
|
||||
|
||||
/**
|
||||
* The Key
|
||||
*
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0";
|
||||
|
||||
/**
|
||||
* The Key Stream for decryption and encryption
|
||||
*
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $stream;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @return \phpseclib\Crypt\RC4
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct(Base::MODE_STREAM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
switch ($engine) {
|
||||
case Base::ENGINE_OPENSSL:
|
||||
switch (strlen($this->key)) {
|
||||
case 5:
|
||||
$this->cipher_name_openssl = 'rc4-40';
|
||||
break;
|
||||
case 8:
|
||||
$this->cipher_name_openssl = 'rc4-64';
|
||||
break;
|
||||
case 16:
|
||||
$this->cipher_name_openssl = 'rc4';
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* RC4 does not use an IV
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function usesIV()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Keys can be between 1 and 256 bytes long.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length is invalid
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length < 8 || $length > 2048) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported');
|
||||
}
|
||||
|
||||
$this->key_length = $length >> 3;
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Keys can be between 1 and 256 bytes long.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length is invalid
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
$length = strlen($key);
|
||||
if ($length < 1 || $length > 256) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @see self::_crypt()
|
||||
* @access public
|
||||
* @param string $plaintext
|
||||
* @return string $ciphertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
if ($this->engine != Base::ENGINE_INTERNAL) {
|
||||
return parent::encrypt($plaintext);
|
||||
}
|
||||
return $this->_crypt($plaintext, self::ENCRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a message.
|
||||
*
|
||||
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
|
||||
* At least if the continuous buffer is disabled.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @see self::_crypt()
|
||||
* @access public
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->engine != Base::ENGINE_INTERNAL) {
|
||||
return parent::decrypt($ciphertext);
|
||||
}
|
||||
return $this->_crypt($ciphertext, self::DECRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param string $in
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
// RC4 does not utilize this method
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param string $in
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
// RC4 does not utilize this method
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
{
|
||||
$key = $this->key;
|
||||
$keyLength = strlen($key);
|
||||
$keyStream = range(0, 255);
|
||||
$j = 0;
|
||||
for ($i = 0; $i < 256; $i++) {
|
||||
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
|
||||
$temp = $keyStream[$i];
|
||||
$keyStream[$i] = $keyStream[$j];
|
||||
$keyStream[$j] = $temp;
|
||||
}
|
||||
|
||||
$this->stream = array();
|
||||
$this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = array(
|
||||
0, // index $i
|
||||
0, // index $j
|
||||
$keyStream
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts a message.
|
||||
*
|
||||
* @see self::encrypt()
|
||||
* @see self::decrypt()
|
||||
* @access private
|
||||
* @param string $text
|
||||
* @param int $mode
|
||||
* @return string $text
|
||||
*/
|
||||
function _crypt($text, $mode)
|
||||
{
|
||||
if ($this->changed) {
|
||||
$this->_setup();
|
||||
$this->changed = false;
|
||||
}
|
||||
|
||||
$stream = &$this->stream[$mode];
|
||||
if ($this->continuousBuffer) {
|
||||
$i = &$stream[0];
|
||||
$j = &$stream[1];
|
||||
$keyStream = &$stream[2];
|
||||
} else {
|
||||
$i = $stream[0];
|
||||
$j = $stream[1];
|
||||
$keyStream = $stream[2];
|
||||
}
|
||||
|
||||
$len = strlen($text);
|
||||
for ($k = 0; $k < $len; ++$k) {
|
||||
$i = ($i + 1) & 255;
|
||||
$ksi = $keyStream[$i];
|
||||
$j = ($j + $ksi) & 255;
|
||||
$ksj = $keyStream[$j];
|
||||
|
||||
$keyStream[$i] = $ksj;
|
||||
$keyStream[$j] = $ksi;
|
||||
$text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
2250
extlib/phpseclib/Crypt/RSA.php
Normal file
2250
extlib/phpseclib/Crypt/RSA.php
Normal file
File diff suppressed because it is too large
Load Diff
224
extlib/phpseclib/Crypt/RSA/MSBLOB.php
Normal file
224
extlib/phpseclib/Crypt/RSA/MSBLOB.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* Miccrosoft BLOB Formatted RSA Key Handler
|
||||
*
|
||||
* More info:
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375601(v=vs.85).aspx
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Microsoft BLOB Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class MSBLOB
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Public/Private Key Pair
|
||||
*/
|
||||
const PRIVATEKEYBLOB = 0x7;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const PUBLICKEYBLOB = 0x6;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const PUBLICKEYBLOBEX = 0xA;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
const CALG_RSA_KEYX = 0x0000A400;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
const CALG_RSA_SIGN = 0x00002400;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const RSA1 = 0x31415352;
|
||||
/**
|
||||
* Private Key
|
||||
*/
|
||||
const RSA2 = 0x32415352;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$key = Base64::decode($key);
|
||||
|
||||
if (!is_string($key) || strlen($key) < 20) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PUBLICKEYSTRUC publickeystruc
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
|
||||
extract(unpack('atype/aversion/vreserved/Valgo', self::_string_shift($key, 8)));
|
||||
switch (ord($type)) {
|
||||
case self::PUBLICKEYBLOB:
|
||||
case self::PUBLICKEYBLOBEX:
|
||||
$publickey = true;
|
||||
break;
|
||||
case self::PRIVATEKEYBLOB:
|
||||
$publickey = false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => $publickey);
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
|
||||
switch ($algo) {
|
||||
case self::CALG_RSA_KEYX:
|
||||
case self::CALG_RSA_SIGN:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// RSAPUBKEY rsapubkey
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx
|
||||
// could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit
|
||||
extract(unpack('Vmagic/Vbitlen/a4pubexp', self::_string_shift($key, 12)));
|
||||
switch ($magic) {
|
||||
case self::RSA2:
|
||||
$components['isPublicKey'] = false;
|
||||
case self::RSA1:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$baseLength = $bitlen / 16;
|
||||
if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
|
||||
// BYTE modulus[rsapubkey.bitlen/8]
|
||||
$components['modulus'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
|
||||
|
||||
if ($publickey) {
|
||||
return $components;
|
||||
}
|
||||
|
||||
$components['isPublicKey'] = false;
|
||||
|
||||
// BYTE prime1[rsapubkey.bitlen/16]
|
||||
$components['primes'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
// BYTE prime2[rsapubkey.bitlen/16]
|
||||
$components['primes'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
|
||||
// BYTE exponent1[rsapubkey.bitlen/16]
|
||||
$components['exponents'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
// BYTE exponent2[rsapubkey.bitlen/16]
|
||||
$components['exponents'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
|
||||
// BYTE coefficient[rsapubkey.bitlen/16]
|
||||
$components['coefficients'] = array(2 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
if (isset($components['privateExponent'])) {
|
||||
$components['publicExponent'] = $components['privateExponent'];
|
||||
}
|
||||
// BYTE privateExponent[rsapubkey.bitlen/8]
|
||||
$components['privateExponent'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$n = strrev($n->toBytes());
|
||||
$e = str_pad(strrev($e->toBytes()), 4, "\0");
|
||||
$key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
|
||||
$key.= pack('VVa*', self::RSA2, 8 * strlen($n), $e);
|
||||
$key.= $n;
|
||||
$key.= strrev($primes[1]->toBytes());
|
||||
$key.= strrev($primes[2]->toBytes());
|
||||
$key.= strrev($exponents[1]->toBytes());
|
||||
$key.= strrev($exponents[2]->toBytes());
|
||||
$key.= strrev($coefficients[1]->toBytes());
|
||||
$key.= strrev($d->toBytes());
|
||||
|
||||
return Base64::encode($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$n = strrev($n->toBytes());
|
||||
$e = str_pad(strrev($e->toBytes()), 4, "\0");
|
||||
$key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
|
||||
$key.= pack('VVa*', self::RSA1, 8 * strlen($n), $e);
|
||||
$key.= $n;
|
||||
|
||||
return Base64::encode($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
141
extlib/phpseclib/Crypt/RSA/OpenSSH.php
Normal file
141
extlib/phpseclib/Crypt/RSA/OpenSSH.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Place in $HOME/.ssh/authorized_keys
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class OpenSSH
|
||||
{
|
||||
/**
|
||||
* Default comment
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $comment = 'phpseclib-generated-key';
|
||||
|
||||
/**
|
||||
* Sets the default comment
|
||||
*
|
||||
* @access public
|
||||
* @param string $comment
|
||||
*/
|
||||
static function setComment($comment)
|
||||
{
|
||||
self::$comment = str_replace(array("\r", "\n"), '', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts = explode(' ', $key, 3);
|
||||
|
||||
$key = isset($parts[1]) ? Base64::decode($parts[1]) : Base64::decode($parts[0]);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$comment = isset($parts[2]) ? $parts[2] : false;
|
||||
|
||||
if (substr($key, 0, 11) != "\0\0\0\7ssh-rsa") {
|
||||
return false;
|
||||
}
|
||||
self::_string_shift($key, 11);
|
||||
if (strlen($key) <= 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', self::_string_shift($key, 4)));
|
||||
if (strlen($key) <= $length) {
|
||||
return false;
|
||||
}
|
||||
$publicExponent = new BigInteger(self::_string_shift($key, $length), -256);
|
||||
if (strlen($key) <= 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', self::_string_shift($key, 4)));
|
||||
if (strlen($key) != $length) {
|
||||
return false;
|
||||
}
|
||||
$modulus = new BigInteger(self::_string_shift($key, $length), -256);
|
||||
|
||||
return array(
|
||||
'isPublicKey' => true,
|
||||
'modulus' => $modulus,
|
||||
'publicExponent' => $publicExponent,
|
||||
'comment' => $comment
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$publicExponent = $e->toBytes(true);
|
||||
$modulus = $n->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc4253#page-15>:
|
||||
// string "ssh-rsa"
|
||||
// mpint e
|
||||
// mpint n
|
||||
$RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
|
||||
$RSAPublicKey = 'ssh-rsa ' . Base64::encode($RSAPublicKey) . ' ' . self::$comment;
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
487
extlib/phpseclib/Crypt/RSA/PKCS.php
Normal file
487
extlib/phpseclib/Crypt/RSA/PKCS.php
Normal file
@ -0,0 +1,487 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\Base;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\TripleDES;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
abstract class PKCS
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\RSA::createKey()
|
||||
*/
|
||||
/**
|
||||
* ASN1 Integer
|
||||
*/
|
||||
const ASN1_INTEGER = 2;
|
||||
/**
|
||||
* ASN1 Bit String
|
||||
*/
|
||||
const ASN1_BITSTRING = 3;
|
||||
/**
|
||||
* ASN1 Octet String
|
||||
*/
|
||||
const ASN1_OCTETSTRING = 4;
|
||||
/**
|
||||
* ASN1 Object Identifier
|
||||
*/
|
||||
const ASN1_OBJECT = 6;
|
||||
/**
|
||||
* ASN1 Sequence (with the constucted bit set)
|
||||
*/
|
||||
const ASN1_SEQUENCE = 48;
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Auto-detect the format
|
||||
*/
|
||||
const MODE_ANY = 0;
|
||||
/**
|
||||
* Require base64-encoded PEM's be supplied
|
||||
*/
|
||||
const MODE_PEM = 1;
|
||||
/**
|
||||
* Require raw DER's be supplied
|
||||
*/
|
||||
const MODE_DER = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Is the key a base-64 encoded PEM, DER or should it be auto-detected?
|
||||
*
|
||||
* @access private
|
||||
* @param int
|
||||
*/
|
||||
static $format = self::MODE_ANY;
|
||||
|
||||
/**
|
||||
* Returns the mode constant corresponding to the mode string
|
||||
*
|
||||
* @access public
|
||||
* @param string $mode
|
||||
* @return int
|
||||
* @throws \UnexpectedValueException if the block cipher mode is unsupported
|
||||
*/
|
||||
static function getEncryptionMode($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
case 'CBC':
|
||||
return Base::MODE_CBC;
|
||||
case 'ECB':
|
||||
return Base::MODE_ECB;
|
||||
case 'CFB':
|
||||
return Base::MODE_CFB;
|
||||
case 'OFB':
|
||||
return Base::MODE_OFB;
|
||||
case 'CTR':
|
||||
return Base::MODE_CTR;
|
||||
}
|
||||
throw new \UnexpectedValueException('Unsupported block cipher mode of operation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cipher object corresponding to a string
|
||||
*
|
||||
* @access public
|
||||
* @param string $algo
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException if the encryption algorithm is unsupported
|
||||
*/
|
||||
static function getEncryptionObject($algo)
|
||||
{
|
||||
$modes = '(CBC|ECB|CFB|OFB|CTR)';
|
||||
switch (true) {
|
||||
case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches):
|
||||
$cipher = new AES(self::getEncryptionMode($matches[2]));
|
||||
$cipher->setKeyLength($matches[1]);
|
||||
return $cipher;
|
||||
case preg_match("#^DES-EDE3-$modes$#", $algo, $matches):
|
||||
return new TripleDES(self::getEncryptionMode($matches[1]));
|
||||
case preg_match("#^DES-$modes$#", $algo, $matches):
|
||||
return new DES(self::getEncryptionMode($matches[1]));
|
||||
default:
|
||||
throw new \UnexpectedValueException('Unsupported encryption algorithmn');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a symmetric key for PKCS#1 keys
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @param string $iv
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function generateSymmetricKey($password, $iv, $length)
|
||||
{
|
||||
$symkey = '';
|
||||
$iv = substr($iv, 0, 8);
|
||||
while (strlen($symkey) < $length) {
|
||||
$symkey.= md5($symkey . $password . $iv, true);
|
||||
}
|
||||
return substr($symkey, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => strpos($key, 'PUBLIC') !== false);
|
||||
|
||||
/* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
|
||||
"outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
|
||||
protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
|
||||
two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
|
||||
|
||||
http://tools.ietf.org/html/rfc1421#section-4.6.1.1
|
||||
http://tools.ietf.org/html/rfc1421#section-4.6.1.3
|
||||
|
||||
DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
|
||||
DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
|
||||
function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
|
||||
own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
|
||||
implementation are part of the standard, as well.
|
||||
|
||||
* OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
|
||||
if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
|
||||
$iv = Hex::decode(trim($matches[2]));
|
||||
// remove the Proc-Type / DEK-Info sections as they're no longer needed
|
||||
$key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
|
||||
$ciphertext = self::_extractBER($key);
|
||||
if ($ciphertext === false) {
|
||||
$ciphertext = $key;
|
||||
}
|
||||
$crypto = self::getEncryptionObject($matches[1]);
|
||||
$crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3));
|
||||
$crypto->setIV($iv);
|
||||
$key = $crypto->decrypt($ciphertext);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (self::$format != self::MODE_DER) {
|
||||
$decoded = self::_extractBER($key);
|
||||
if ($decoded !== false) {
|
||||
$key = $decoded;
|
||||
} elseif (self::$format == self::MODE_PEM) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tag = ord(self::_string_shift($key));
|
||||
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
||||
|
||||
0:d=0 hl=4 l= 631 cons: SEQUENCE
|
||||
4:d=1 hl=2 l= 1 prim: INTEGER :00
|
||||
7:d=1 hl=2 l= 13 cons: SEQUENCE
|
||||
9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
||||
20:d=2 hl=2 l= 0 prim: NULL
|
||||
22:d=1 hl=4 l= 609 prim: OCTET STRING
|
||||
|
||||
ie. PKCS8 keys */
|
||||
|
||||
if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
|
||||
self::_string_shift($key, 3);
|
||||
$tag = self::ASN1_SEQUENCE;
|
||||
}
|
||||
|
||||
if ($tag == self::ASN1_SEQUENCE) {
|
||||
$temp = self::_string_shift($key, self::_decodeLength($key));
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_OBJECT) {
|
||||
return false;
|
||||
}
|
||||
$length = self::_decodeLength($temp);
|
||||
switch (self::_string_shift($temp, $length)) {
|
||||
case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
|
||||
break;
|
||||
case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
|
||||
/*
|
||||
PBEParameter ::= SEQUENCE {
|
||||
salt OCTET STRING (SIZE(8)),
|
||||
iterationCount INTEGER }
|
||||
*/
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($temp) != strlen($temp)) {
|
||||
return false;
|
||||
}
|
||||
self::_string_shift($temp); // assume it's an octet string
|
||||
$salt = self::_string_shift($temp, self::_decodeLength($temp));
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($temp);
|
||||
list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
|
||||
self::_string_shift($key); // assume it's an octet string
|
||||
$length = self::_decodeLength($key);
|
||||
if (strlen($key) != $length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$crypto = new DES(DES::MODE_CBC);
|
||||
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
|
||||
$key = $crypto->decrypt($key);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
return self::load($key);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
||||
|
||||
0:d=0 hl=4 l= 290 cons: SEQUENCE
|
||||
4:d=1 hl=2 l= 13 cons: SEQUENCE
|
||||
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
||||
17:d=2 hl=2 l= 0 prim: NULL
|
||||
19:d=1 hl=4 l= 271 prim: BIT STRING */
|
||||
$tag = ord(self::_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
|
||||
self::_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
|
||||
// "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
|
||||
// unused bits in the final subsequent octet. The number shall be in the range zero to seven."
|
||||
// -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
|
||||
if ($tag == self::ASN1_BITSTRING) {
|
||||
self::_string_shift($key);
|
||||
}
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
$tag = ord(self::_string_shift($key));
|
||||
}
|
||||
if ($tag != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = self::_decodeLength($key);
|
||||
$temp = self::_string_shift($key, $length);
|
||||
if (strlen($temp) != 1 || ord($temp) > 2) {
|
||||
$components['modulus'] = new BigInteger($temp, 256);
|
||||
self::_string_shift($key); // skip over self::ASN1_INTEGER
|
||||
$length = self::_decodeLength($key);
|
||||
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
|
||||
return $components;
|
||||
}
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
$length = self::_decodeLength($key);
|
||||
$components['modulus'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['publicExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
|
||||
if (!empty($key)) {
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($key);
|
||||
while (!empty($key)) {
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($key);
|
||||
$key = substr($key, 1);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['coefficients'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require base64-encoded PEM's be supplied
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requirePEM()
|
||||
{
|
||||
self::$format = self::MODE_PEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require raw DER's be supplied
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requireDER()
|
||||
{
|
||||
self::$format = self::MODE_DER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept any format and auto detect the format
|
||||
*
|
||||
* This is the default setting
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requireAny()
|
||||
{
|
||||
self::$format = self::MODE_ANY;
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-decode the length
|
||||
*
|
||||
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
||||
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
|
||||
*
|
||||
* @access private
|
||||
* @param string $string
|
||||
* @return int
|
||||
*/
|
||||
static function _decodeLength(&$string)
|
||||
{
|
||||
$length = ord(self::_string_shift($string));
|
||||
if ($length & 0x80) { // definite length, long form
|
||||
$length&= 0x7F;
|
||||
$temp = self::_string_shift($string, $length);
|
||||
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-encode the length
|
||||
*
|
||||
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
||||
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
|
||||
*
|
||||
* @access private
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function _encodeLength($length)
|
||||
{
|
||||
if ($length <= 0x7F) {
|
||||
return chr($length);
|
||||
}
|
||||
|
||||
$temp = ltrim(pack('N', $length), chr(0));
|
||||
return pack('Ca*', 0x80 | strlen($temp), $temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract raw BER from Base64 encoding
|
||||
*
|
||||
* @access private
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
static function _extractBER($str)
|
||||
{
|
||||
/* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
|
||||
* above and beyond the ceritificate.
|
||||
* ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
|
||||
*
|
||||
* Bag Attributes
|
||||
* localKeyID: 01 00 00 00
|
||||
* subject=/O=organization/OU=org unit/CN=common name
|
||||
* issuer=/O=organization/CN=common name
|
||||
*/
|
||||
$temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
|
||||
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
|
||||
$temp = preg_replace('#-+[^-]+-+#', '', $temp);
|
||||
// remove new lines
|
||||
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false;
|
||||
return $temp != false ? $temp : $str;
|
||||
}
|
||||
}
|
174
extlib/phpseclib/Crypt/RSA/PKCS1.php
Normal file
174
extlib/phpseclib/Crypt/RSA/PKCS1.php
Normal file
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by File/X509.php
|
||||
*
|
||||
* Has the following header:
|
||||
*
|
||||
* -----BEGIN RSA PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to ssh-keygen's pem format (as specified by -m)
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Crypt\TripleDES;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PKCS1 extends PKCS
|
||||
{
|
||||
/**
|
||||
* Default encryption algorithm
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $defaultEncryptionAlgorithm = 'DES-EDE3-CBC';
|
||||
|
||||
/**
|
||||
* Sets the default encryption algorithm
|
||||
*
|
||||
* @access public
|
||||
* @param string $algo
|
||||
*/
|
||||
static function setEncryptionAlgorithm($algo)
|
||||
{
|
||||
self::$defaultEncryptionAlgorithm = $algo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$num_primes = count($primes);
|
||||
$raw = array(
|
||||
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$components = array();
|
||||
foreach ($raw as $name => $value) {
|
||||
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = implode('', $components);
|
||||
|
||||
if ($num_primes > 2) {
|
||||
$OtherPrimeInfos = '';
|
||||
for ($i = 3; $i <= $num_primes; $i++) {
|
||||
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
|
||||
//
|
||||
// OtherPrimeInfo ::= SEQUENCE {
|
||||
// prime INTEGER, -- ri
|
||||
// exponent INTEGER, -- di
|
||||
// coefficient INTEGER -- ti
|
||||
// }
|
||||
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
|
||||
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
|
||||
}
|
||||
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
if (!empty($password) || is_string($password)) {
|
||||
$cipher = self::getEncryptionObject(self::$defaultEncryptionAlgorithm);
|
||||
$iv = Random::string($cipher->getBlockLength() >> 3);
|
||||
$cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3));
|
||||
$cipher->setIV($iv);
|
||||
$iv = strtoupper(Hex::encode($iv));
|
||||
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
||||
"Proc-Type: 4,ENCRYPTED\r\n" .
|
||||
"DEK-Info: " . self::$defaultEncryptionAlgorithm . ",$iv\r\n" .
|
||||
"\r\n" .
|
||||
chunk_split(Base64::encode($cipher->encrypt($RSAPrivateKey)), 64) .
|
||||
'-----END RSA PRIVATE KEY-----';
|
||||
} else {
|
||||
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END RSA PRIVATE KEY-----';
|
||||
}
|
||||
|
||||
return $RSAPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$modulus = $n->toBytes(true);
|
||||
$publicExponent = $e->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
|
||||
// RSAPublicKey ::= SEQUENCE {
|
||||
// modulus INTEGER, -- n
|
||||
// publicExponent INTEGER -- e
|
||||
// }
|
||||
$components = array(
|
||||
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
|
||||
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
|
||||
);
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
||||
$components['modulus'],
|
||||
$components['publicExponent']
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPublicKey), 64) .
|
||||
'-----END RSA PUBLIC KEY-----';
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
}
|
209
extlib/phpseclib/Crypt/RSA/PKCS8.php
Normal file
209
extlib/phpseclib/Crypt/RSA/PKCS8.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS#8 Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
|
||||
*
|
||||
* Has the following header:
|
||||
*
|
||||
* -----BEGIN PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
|
||||
* is specific to private keys it's basically creating a DER-encoded wrapper
|
||||
* for keys. This just extends that same concept to public keys (much like ssh-keygen)
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#8 Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PKCS8 extends PKCS
|
||||
{
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$num_primes = count($primes);
|
||||
$raw = array(
|
||||
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$components = array();
|
||||
foreach ($raw as $name => $value) {
|
||||
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = implode('', $components);
|
||||
|
||||
if ($num_primes > 2) {
|
||||
$OtherPrimeInfos = '';
|
||||
for ($i = 3; $i <= $num_primes; $i++) {
|
||||
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
|
||||
//
|
||||
// OtherPrimeInfo ::= SEQUENCE {
|
||||
// prime INTEGER, -- ri
|
||||
// exponent INTEGER, -- di
|
||||
// coefficient INTEGER -- ti
|
||||
// }
|
||||
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
|
||||
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
|
||||
}
|
||||
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPrivateKey = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_INTEGER,
|
||||
"\01\00",
|
||||
$rsaOID,
|
||||
4,
|
||||
self::_encodeLength(strlen($RSAPrivateKey)),
|
||||
$RSAPrivateKey
|
||||
);
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
if (!empty($password) || is_string($password)) {
|
||||
$salt = Random::string(8);
|
||||
$iterationCount = 2048;
|
||||
|
||||
$crypto = new DES(DES::MODE_CBC);
|
||||
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
|
||||
$RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
|
||||
|
||||
$parameters = pack(
|
||||
'Ca*a*Ca*N',
|
||||
self::ASN1_OCTETSTRING,
|
||||
self::_encodeLength(strlen($salt)),
|
||||
$salt,
|
||||
self::ASN1_INTEGER,
|
||||
self::_encodeLength(4),
|
||||
$iterationCount
|
||||
);
|
||||
$pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
|
||||
|
||||
$encryptionAlgorithm = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_OBJECT,
|
||||
self::_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
|
||||
$pbeWithMD5AndDES_CBC,
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($parameters)),
|
||||
$parameters
|
||||
);
|
||||
|
||||
$RSAPrivateKey = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($encryptionAlgorithm)),
|
||||
$encryptionAlgorithm,
|
||||
self::ASN1_OCTETSTRING,
|
||||
self::_encodeLength(strlen($RSAPrivateKey)),
|
||||
$RSAPrivateKey
|
||||
);
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
$RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END ENCRYPTED PRIVATE KEY-----';
|
||||
} else {
|
||||
$RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END PRIVATE KEY-----';
|
||||
}
|
||||
|
||||
return $RSAPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$modulus = $n->toBytes(true);
|
||||
$publicExponent = $e->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
|
||||
// RSAPublicKey ::= SEQUENCE {
|
||||
// modulus INTEGER, -- n
|
||||
// publicExponent INTEGER -- e
|
||||
// }
|
||||
$components = array(
|
||||
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
|
||||
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
|
||||
);
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
||||
$components['modulus'],
|
||||
$components['publicExponent']
|
||||
);
|
||||
|
||||
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
|
||||
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPublicKey = chr(0) . $RSAPublicKey;
|
||||
$RSAPublicKey = chr(3) . self::_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($rsaOID . $RSAPublicKey)),
|
||||
$rsaOID . $RSAPublicKey
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPublicKey), 64) .
|
||||
'-----END PUBLIC KEY-----';
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
}
|
313
extlib/phpseclib/Crypt/RSA/PuTTY.php
Normal file
313
extlib/phpseclib/Crypt/RSA/PuTTY.php
Normal file
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\Hash;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PuTTY
|
||||
{
|
||||
/**
|
||||
* Default comment
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $comment = 'phpseclib-generated-key';
|
||||
|
||||
/**
|
||||
* Sets the default comment
|
||||
*
|
||||
* @access public
|
||||
* @param string $comment
|
||||
*/
|
||||
static function setComment($comment)
|
||||
{
|
||||
self::$comment = str_replace(array("\r", "\n"), '', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a symmetric key for PuTTY keys
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @param string $iv
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function generateSymmetricKey($password, $length)
|
||||
{
|
||||
$symkey = '';
|
||||
$sequence = 0;
|
||||
while (strlen($symkey) < $length) {
|
||||
$temp = pack('Na*', $sequence++, $password);
|
||||
$symkey.= Hex::decode(sha1($temp));
|
||||
}
|
||||
return substr($symkey, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static $one;
|
||||
if (!isset($one)) {
|
||||
$one = new BigInteger(1);
|
||||
}
|
||||
|
||||
if (strpos($key, 'BEGIN SSH2 PUBLIC KEY')) {
|
||||
$data = preg_split('#[\r\n]+#', $key);
|
||||
$data = array_splice($data, 2, -1);
|
||||
$data = implode('', $data);
|
||||
|
||||
$components = OpenSSH::load($data);
|
||||
if ($components === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!preg_match('#Comment: "(.+)"#', $key, $matches)) {
|
||||
return false;
|
||||
}
|
||||
$components['comment'] = str_replace(array('\\\\', '\"'), array('\\', '"'), $matches[1]);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => false);
|
||||
$key = preg_split('#\r\n|\r|\n#', $key);
|
||||
$type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
|
||||
if ($type != 'ssh-rsa') {
|
||||
return false;
|
||||
}
|
||||
$encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
|
||||
$components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
|
||||
|
||||
$publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
|
||||
$public = Base64::decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
|
||||
$public = substr($public, 11);
|
||||
extract(unpack('Nlength', self::_string_shift($public, 4)));
|
||||
$components['publicExponent'] = new BigInteger(self::_string_shift($public, $length), -256);
|
||||
extract(unpack('Nlength', self::_string_shift($public, 4)));
|
||||
$components['modulus'] = new BigInteger(self::_string_shift($public, $length), -256);
|
||||
|
||||
$privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4]));
|
||||
$private = Base64::decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
|
||||
|
||||
switch ($encryption) {
|
||||
case 'aes256-cbc':
|
||||
$symkey = static::generateSymmetricKey($password, 32);
|
||||
$crypto = new AES(AES::MODE_CBC);
|
||||
}
|
||||
|
||||
if ($encryption != 'none') {
|
||||
$crypto->setKey($symkey);
|
||||
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||
$crypto->disablePadding();
|
||||
$private = $crypto->decrypt($private);
|
||||
if ($private === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['privateExponent'] = new BigInteger(self::_string_shift($private, $length), -256);
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['primes'] = array(1 => new BigInteger(self::_string_shift($private, $length), -256));
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($private, $length), -256);
|
||||
|
||||
$temp = $components['primes'][1]->subtract($one);
|
||||
$components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
|
||||
$temp = $components['primes'][2]->subtract($one);
|
||||
$components['exponents'][] = $components['publicExponent']->modInverse($temp);
|
||||
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($private, $length), -256));
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$raw = array(
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
|
||||
$encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none';
|
||||
$key.= $encryption;
|
||||
$key.= "\r\nComment: " . self::$comment . "\r\n";
|
||||
$public = pack(
|
||||
'Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($raw['publicExponent']),
|
||||
$raw['publicExponent'],
|
||||
strlen($raw['modulus']),
|
||||
$raw['modulus']
|
||||
);
|
||||
$source = pack(
|
||||
'Na*Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($encryption),
|
||||
$encryption,
|
||||
strlen(self::$comment),
|
||||
self::$comment,
|
||||
strlen($public),
|
||||
$public
|
||||
);
|
||||
$public = Base64::encode($public);
|
||||
$key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
|
||||
$key.= chunk_split($public, 64);
|
||||
$private = pack(
|
||||
'Na*Na*Na*Na*',
|
||||
strlen($raw['privateExponent']),
|
||||
$raw['privateExponent'],
|
||||
strlen($raw['prime1']),
|
||||
$raw['prime1'],
|
||||
strlen($raw['prime2']),
|
||||
$raw['prime2'],
|
||||
strlen($raw['coefficient']),
|
||||
$raw['coefficient']
|
||||
);
|
||||
if (empty($password) && !is_string($password)) {
|
||||
$source.= pack('Na*', strlen($private), $private);
|
||||
$hashkey = 'putty-private-key-file-mac-key';
|
||||
} else {
|
||||
$private.= Random::string(16 - (strlen($private) & 15));
|
||||
$source.= pack('Na*', strlen($private), $private);
|
||||
$crypto = new AES();
|
||||
|
||||
$crypto->setKey(static::generateSymmetricKey($password, 32));
|
||||
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||
$crypto->disablePadding();
|
||||
$private = $crypto->encrypt($private);
|
||||
$hashkey = 'putty-private-key-file-mac-key' . $password;
|
||||
}
|
||||
|
||||
$private = Base64::encode($private);
|
||||
$key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
|
||||
$key.= chunk_split($private, 64);
|
||||
$hash = new Hash('sha1');
|
||||
$hash->setKey(sha1($hashkey, true));
|
||||
$key.= 'Private-MAC: ' . Hex::encode($hash->hash($source)) . "\r\n";
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$n = $n->toBytes(true);
|
||||
$e = $e->toBytes(true);
|
||||
|
||||
$key = pack(
|
||||
'Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($e),
|
||||
$e,
|
||||
strlen($n),
|
||||
$n
|
||||
);
|
||||
$key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" .
|
||||
'Comment: "' . str_replace(array('\\', '"'), array('\\\\', '\"'), self::$comment) . "\"\r\n";
|
||||
chunk_split(Base64::encode($key), 64) .
|
||||
'---- END SSH2 PUBLIC KEY ----';
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
103
extlib/phpseclib/Crypt/RSA/Raw.php
Normal file
103
extlib/phpseclib/Crypt/RSA/Raw.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* An array containing two \phpseclib\Math\BigInteger objects.
|
||||
*
|
||||
* The exponent can be indexed with any of the following:
|
||||
*
|
||||
* 0, e, exponent, publicExponent
|
||||
*
|
||||
* The modulus can be indexed with any of the following:
|
||||
*
|
||||
* 1, n, modulo, modulus
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class Raw
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_array($key)) {
|
||||
return false;
|
||||
}
|
||||
if (isset($key['isPublicKey']) && isset($key['modulus'])) {
|
||||
if (isset($key['privateExponent']) || isset($key['publicExponent'])) {
|
||||
if (!isset($key['primes'])) {
|
||||
return $key;
|
||||
}
|
||||
if (isset($key['exponents']) && isset($key['coefficients']) && isset($key['publicExponent']) && isset($key['privateExponent'])) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
$components = array('isPublicKey' => true);
|
||||
switch (true) {
|
||||
case isset($key['e']):
|
||||
$components['publicExponent'] = $key['e'];
|
||||
break;
|
||||
case isset($key['exponent']):
|
||||
$components['publicExponent'] = $key['exponent'];
|
||||
break;
|
||||
case isset($key['publicExponent']):
|
||||
$components['publicExponent'] = $key['publicExponent'];
|
||||
break;
|
||||
case isset($key[0]):
|
||||
$components['publicExponent'] = $key[0];
|
||||
}
|
||||
switch (true) {
|
||||
case isset($key['n']):
|
||||
$components['modulus'] = $key['n'];
|
||||
break;
|
||||
case isset($key['modulo']):
|
||||
$components['modulus'] = $key['modulo'];
|
||||
break;
|
||||
case isset($key['modulus']):
|
||||
$components['modulus'] = $key['modulus'];
|
||||
break;
|
||||
case isset($key[1]):
|
||||
$components['modulus'] = $key[1];
|
||||
}
|
||||
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
return array('e' => clone $e, 'n' => clone $n);
|
||||
}
|
||||
}
|
147
extlib/phpseclib/Crypt/RSA/XML.php
Normal file
147
extlib/phpseclib/Crypt/RSA/XML.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* More info:
|
||||
*
|
||||
* http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
|
||||
* http://en.wikipedia.org/wiki/XML_Signature
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class XML
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array(
|
||||
'isPublicKey' => false,
|
||||
'primes' => array(),
|
||||
'exponents' => array(),
|
||||
'coefficients' => array()
|
||||
);
|
||||
|
||||
$use_errors = libxml_use_internal_errors(true);
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
if (!$dom->loadXML('<xml>' . $key . '</xml>')) {
|
||||
return false;
|
||||
}
|
||||
$xpath = new \DOMXPath($dom);
|
||||
$keys = array('modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd');
|
||||
foreach ($keys as $key) {
|
||||
// $dom->getElementsByTagName($key) is case-sensitive
|
||||
$temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']");
|
||||
if (!$temp->length) {
|
||||
continue;
|
||||
}
|
||||
$value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256);
|
||||
switch ($key) {
|
||||
case 'modulus':
|
||||
$components['modulus'] = $value;
|
||||
break;
|
||||
case 'exponent':
|
||||
$components['publicExponent'] = $value;
|
||||
break;
|
||||
case 'p':
|
||||
$components['primes'][1] = $value;
|
||||
break;
|
||||
case 'q':
|
||||
$components['primes'][2] = $value;
|
||||
break;
|
||||
case 'dp':
|
||||
$components['exponents'][1] = $value;
|
||||
break;
|
||||
case 'dq':
|
||||
$components['exponents'][2] = $value;
|
||||
break;
|
||||
case 'inverseq':
|
||||
$components['coefficients'][2] = $value;
|
||||
break;
|
||||
case 'd':
|
||||
$components['privateExponent'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
libxml_use_internal_errors($use_errors);
|
||||
|
||||
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
return false;
|
||||
}
|
||||
return "<RSAKeyValue>\r\n" .
|
||||
' <Modulus>' . Base64::encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Base64::encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
' <P>' . Base64::encode($primes[1]->toBytes()) . "</P>\r\n" .
|
||||
' <Q>' . Base64::encode($primes[2]->toBytes()) . "</Q>\r\n" .
|
||||
' <DP>' . Base64::encode($exponents[1]->toBytes()) . "</DP>\r\n" .
|
||||
' <DQ>' . Base64::encode($exponents[2]->toBytes()) . "</DQ>\r\n" .
|
||||
' <InverseQ>' . Base64::encode($coefficients[2]->toBytes()) . "</InverseQ>\r\n" .
|
||||
' <D>' . Base64::encode($d->toBytes()) . "</D>\r\n" .
|
||||
'</RSAKeyValue>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
return "<RSAKeyValue>\r\n" .
|
||||
' <Modulus>' . Base64::encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Base64::encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
'</RSAKeyValue>';
|
||||
}
|
||||
}
|
219
extlib/phpseclib/Crypt/Random.php
Normal file
219
extlib/phpseclib/Crypt/Random.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Random Number Generator
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* echo bin2hex(\phpseclib\Crypt\Random::string(8));
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Random
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP Random Number Generator
|
||||
*
|
||||
* @package Random
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class Random
|
||||
{
|
||||
/**
|
||||
* Generate a random string.
|
||||
*
|
||||
* Although microoptimizations are generally discouraged as they impair readability this function is ripe with
|
||||
* microoptimizations because this function has the potential of being called a huge number of times.
|
||||
* eg. for RSA key generation.
|
||||
*
|
||||
* @param int $length
|
||||
* @throws \RuntimeException if a symmetric cipher is needed but not loaded
|
||||
* @return string
|
||||
*/
|
||||
static function string($length)
|
||||
{
|
||||
try {
|
||||
return \random_bytes($length);
|
||||
} catch (\Exception $e) {
|
||||
// random_compat will throw an Exception, which in PHP 5 does not implement Throwable
|
||||
} catch (\Throwable $e) {
|
||||
// If a sufficient source of randomness is unavailable, random_bytes() will throw an
|
||||
// object that implements the Throwable interface (Exception, TypeError, Error).
|
||||
// We don't actually need to do anything here. The string() method should just continue
|
||||
// as normal. Note, however, that if we don't have a sufficient source of randomness for
|
||||
// random_bytes(), most of the other calls here will fail too, so we'll end up using
|
||||
// the PHP implementation.
|
||||
}
|
||||
// at this point we have no choice but to use a pure-PHP CSPRNG
|
||||
|
||||
// cascade entropy across multiple PHP instances by fixing the session and collecting all
|
||||
// environmental variables, including the previous session data and the current session
|
||||
// data.
|
||||
//
|
||||
// mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
|
||||
// easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
|
||||
// PHP isn't low level to be able to use those as sources and on a web server there's not likely
|
||||
// going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
|
||||
// however, a ton of people visiting the website. obviously you don't want to base your seeding
|
||||
// soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
|
||||
// by the user and (2) this isn't just looking at the data sent by the current user - it's based
|
||||
// on the data sent by all users. one user requests the page and a hash of their info is saved.
|
||||
// another user visits the page and the serialization of their data is utilized along with the
|
||||
// server envirnment stuff and a hash of the previous http request data (which itself utilizes
|
||||
// a hash of the session data before that). certainly an attacker should be assumed to have
|
||||
// full control over his own http requests. he, however, is not going to have control over
|
||||
// everyone's http requests.
|
||||
static $crypto = false, $v;
|
||||
if ($crypto === false) {
|
||||
// save old session data
|
||||
$old_session_id = session_id();
|
||||
$old_use_cookies = ini_get('session.use_cookies');
|
||||
$old_session_cache_limiter = session_cache_limiter();
|
||||
$_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
|
||||
if ($old_session_id != '') {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
session_id(1);
|
||||
ini_set('session.use_cookies', 0);
|
||||
session_cache_limiter('');
|
||||
session_start();
|
||||
|
||||
$v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') .
|
||||
(isset($_POST) ? self::safe_serialize($_POST) : '') .
|
||||
(isset($_GET) ? self::safe_serialize($_GET) : '') .
|
||||
(isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') .
|
||||
self::safe_serialize($GLOBALS) .
|
||||
self::safe_serialize($_SESSION) .
|
||||
self::safe_serialize($_OLD_SESSION);
|
||||
$v = $seed = $_SESSION['seed'] = sha1($v, true);
|
||||
if (!isset($_SESSION['count'])) {
|
||||
$_SESSION['count'] = 0;
|
||||
}
|
||||
$_SESSION['count']++;
|
||||
|
||||
session_write_close();
|
||||
|
||||
// restore old session data
|
||||
if ($old_session_id != '') {
|
||||
session_id($old_session_id);
|
||||
session_start();
|
||||
ini_set('session.use_cookies', $old_use_cookies);
|
||||
session_cache_limiter($old_session_cache_limiter);
|
||||
} else {
|
||||
if ($_OLD_SESSION !== false) {
|
||||
$_SESSION = $_OLD_SESSION;
|
||||
unset($_OLD_SESSION);
|
||||
} else {
|
||||
unset($_SESSION);
|
||||
}
|
||||
}
|
||||
|
||||
// in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
|
||||
// the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
|
||||
// if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
|
||||
// original hash and the current hash. we'll be emulating that. for more info see the following URL:
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc4253#section-7.2
|
||||
//
|
||||
// see the is_string($crypto) part for an example of how to expand the keys
|
||||
$key = sha1($seed . 'A', true);
|
||||
$iv = sha1($seed . 'C', true);
|
||||
|
||||
// ciphers are used as per the nist.gov link below. also, see this link:
|
||||
//
|
||||
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
|
||||
switch (true) {
|
||||
case class_exists('\phpseclib\Crypt\AES'):
|
||||
$crypto = new AES(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\Twofish'):
|
||||
$crypto = new Twofish(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\Blowfish'):
|
||||
$crypto = new Blowfish(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\TripleDES'):
|
||||
$crypto = new TripleDES(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\DES'):
|
||||
$crypto = new DES(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\RC4'):
|
||||
$crypto = new RC4();
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
||||
}
|
||||
|
||||
$crypto->setKey($key);
|
||||
$crypto->setIV($iv);
|
||||
$crypto->enableContinuousBuffer();
|
||||
}
|
||||
|
||||
//return $crypto->encrypt(str_repeat("\0", $length));
|
||||
|
||||
// the following is based off of ANSI X9.31:
|
||||
//
|
||||
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
|
||||
//
|
||||
// OpenSSL uses that same standard for it's random numbers:
|
||||
//
|
||||
// http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
|
||||
// (do a search for "ANS X9.31 A.2.4")
|
||||
$result = '';
|
||||
while (strlen($result) < $length) {
|
||||
$i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
|
||||
$r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
|
||||
$v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
|
||||
$result.= $r;
|
||||
}
|
||||
return substr($result, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely serialize variables
|
||||
*
|
||||
* If a class has a private __sleep() it'll emit a warning
|
||||
*
|
||||
* @param mixed $arr
|
||||
* @access public
|
||||
*/
|
||||
function safe_serialize(&$arr)
|
||||
{
|
||||
if (is_object($arr)) {
|
||||
return '';
|
||||
}
|
||||
if (!is_array($arr)) {
|
||||
return serialize($arr);
|
||||
}
|
||||
// prevent circular array recursion
|
||||
if (isset($arr['__phpseclib_marker'])) {
|
||||
return '';
|
||||
}
|
||||
$safearr = array();
|
||||
$arr['__phpseclib_marker'] = true;
|
||||
foreach (array_keys($arr) as $key) {
|
||||
// do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
|
||||
if ($key !== '__phpseclib_marker') {
|
||||
$safearr[$key] = self::safe_serialize($arr[$key]);
|
||||
}
|
||||
}
|
||||
unset($arr['__phpseclib_marker']);
|
||||
return serialize($safearr);
|
||||
}
|
||||
}
|
977
extlib/phpseclib/Crypt/Rijndael.php
Normal file
977
extlib/phpseclib/Crypt/Rijndael.php
Normal file
@ -0,0 +1,977 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Rijndael.
|
||||
*
|
||||
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* If {@link self::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
|
||||
* {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
||||
* {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
|
||||
* 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
|
||||
* {@link self::setKey() setKey()} is called, again, at which point, it'll be recalculated.
|
||||
*
|
||||
* Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
|
||||
* does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
|
||||
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
|
||||
* algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
|
||||
* are first defined as valid key / block lengths in
|
||||
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
|
||||
* Extensions: Other block and Cipher Key lengths.
|
||||
* Note: Use of 160/224-bit Keys must be explicitly set by setKeyLength(160) respectively setKeyLength(224).
|
||||
*
|
||||
* {@internal The variable names are the same as those in
|
||||
* {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $rijndael = new \phpseclib\Crypt\Rijndael();
|
||||
*
|
||||
* $rijndael->setKey('abcdefghijklmnop');
|
||||
*
|
||||
* $size = 10 * 1024;
|
||||
* $plaintext = '';
|
||||
* for ($i = 0; $i < $size; $i++) {
|
||||
* $plaintext.= 'a';
|
||||
* }
|
||||
*
|
||||
* echo $rijndael->decrypt($rijndael->encrypt($plaintext));
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Rijndael
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2008 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Rijndael.
|
||||
*
|
||||
* @package Rijndael
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class Rijndael extends Base
|
||||
{
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not.
|
||||
* \phpseclib\Crypt\Rijndael determines automatically whether mcrypt is useable
|
||||
* or not for the current $block_size/$key_length.
|
||||
* In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @see \phpseclib\Crypt\Base::engine
|
||||
* @see self::isValidEngine()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'rijndael-128';
|
||||
|
||||
/**
|
||||
* The default salt used by setPassword()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_default_salt
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $password_default_salt = 'phpseclib';
|
||||
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see self::_setup()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $w;
|
||||
|
||||
/**
|
||||
* The Inverse Key Schedule
|
||||
*
|
||||
* @see self::_setup()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $dw;
|
||||
|
||||
/**
|
||||
* The Block Length divided by 32
|
||||
*
|
||||
* @see self::setBlockLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
|
||||
* derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
||||
* of that, we'll just precompute it once.
|
||||
*/
|
||||
var $Nb = 4;
|
||||
|
||||
/**
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* @see self::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
|
||||
* derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
||||
* of that, we'll just precompute it once.
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* The Key Length divided by 32
|
||||
*
|
||||
* @see self::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
|
||||
*/
|
||||
var $Nk = 4;
|
||||
|
||||
/**
|
||||
* The Number of Rounds
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 14, the min value is 10.
|
||||
*/
|
||||
var $Nr;
|
||||
|
||||
/**
|
||||
* Shift offsets
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $c;
|
||||
|
||||
/**
|
||||
* Holds the last used key- and block_size information
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function __construct($mode)
|
||||
{
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 128, 160, 192, 224, and 256.
|
||||
*
|
||||
* Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
|
||||
* and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
|
||||
* 192/256 bits as, for example, mcrypt will do.
|
||||
*
|
||||
* That said, if you want be compatible with other Rijndael and AES implementations,
|
||||
* you should not setKeyLength(160) or setKeyLength(224).
|
||||
*
|
||||
* Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use
|
||||
* the mcrypt php extension, even if available.
|
||||
* This results then in slower encryption.
|
||||
*
|
||||
* @access public
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 160:
|
||||
case 192:
|
||||
case 224:
|
||||
case 256:
|
||||
$this->key_length = $length >> 3;
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Rijndael supports five different key lengths
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 20:
|
||||
case 24:
|
||||
case 28:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block length
|
||||
*
|
||||
* Valid block lengths are 128, 160, 192, 224, and 256.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
*/
|
||||
function setBlockLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 160:
|
||||
case 192:
|
||||
case 224:
|
||||
case 256:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
|
||||
}
|
||||
|
||||
$this->Nb = $length >> 5;
|
||||
$this->block_size = $length >> 3;
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
switch ($engine) {
|
||||
case self::ENGINE_OPENSSL:
|
||||
if ($this->block_size != 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
|
||||
$this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
|
||||
break;
|
||||
case self::ENGINE_MCRYPT:
|
||||
$this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
|
||||
if ($this->key_length % 8) { // is it a 160/224-bit key?
|
||||
// mcrypt is not usable for them, only for 128/192/256-bit keys
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
static $tables;
|
||||
if (empty($tables)) {
|
||||
$tables = &$this->_getTables();
|
||||
}
|
||||
$t0 = $tables[0];
|
||||
$t1 = $tables[1];
|
||||
$t2 = $tables[2];
|
||||
$t3 = $tables[3];
|
||||
$sbox = $tables[4];
|
||||
|
||||
$state = array();
|
||||
$words = unpack('N*', $in);
|
||||
|
||||
$c = $this->c;
|
||||
$w = $this->w;
|
||||
$Nb = $this->Nb;
|
||||
$Nr = $this->Nr;
|
||||
|
||||
// addRoundKey
|
||||
$wc = $Nb - 1;
|
||||
foreach ($words as $word) {
|
||||
$state[] = $word ^ $w[++$wc];
|
||||
}
|
||||
|
||||
// fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
|
||||
// subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
|
||||
// Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
|
||||
// Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
|
||||
// Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
|
||||
// equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
|
||||
|
||||
// [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
|
||||
$temp = array();
|
||||
for ($round = 1; $round < $Nr; ++$round) {
|
||||
$i = 0; // $c[0] == 0
|
||||
$j = $c[1];
|
||||
$k = $c[2];
|
||||
$l = $c[3];
|
||||
|
||||
while ($i < $Nb) {
|
||||
$temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^
|
||||
$t1[$state[$j] >> 16 & 0x000000FF] ^
|
||||
$t2[$state[$k] >> 8 & 0x000000FF] ^
|
||||
$t3[$state[$l] & 0x000000FF] ^
|
||||
$w[++$wc];
|
||||
++$i;
|
||||
$j = ($j + 1) % $Nb;
|
||||
$k = ($k + 1) % $Nb;
|
||||
$l = ($l + 1) % $Nb;
|
||||
}
|
||||
$state = $temp;
|
||||
}
|
||||
|
||||
// subWord
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$state[$i] = $sbox[$state[$i] & 0x000000FF] |
|
||||
($sbox[$state[$i] >> 8 & 0x000000FF] << 8) |
|
||||
($sbox[$state[$i] >> 16 & 0x000000FF] << 16) |
|
||||
($sbox[$state[$i] >> 24 & 0x000000FF] << 24);
|
||||
}
|
||||
|
||||
// shiftRows + addRoundKey
|
||||
$i = 0; // $c[0] == 0
|
||||
$j = $c[1];
|
||||
$k = $c[2];
|
||||
$l = $c[3];
|
||||
while ($i < $Nb) {
|
||||
$temp[$i] = ($state[$i] & 0xFF000000) ^
|
||||
($state[$j] & 0x00FF0000) ^
|
||||
($state[$k] & 0x0000FF00) ^
|
||||
($state[$l] & 0x000000FF) ^
|
||||
$w[$i];
|
||||
++$i;
|
||||
$j = ($j + 1) % $Nb;
|
||||
$k = ($k + 1) % $Nb;
|
||||
$l = ($l + 1) % $Nb;
|
||||
}
|
||||
|
||||
switch ($Nb) {
|
||||
case 8:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
|
||||
case 7:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
|
||||
case 6:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
|
||||
case 5:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
|
||||
default:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
static $invtables;
|
||||
if (empty($invtables)) {
|
||||
$invtables = &$this->_getInvTables();
|
||||
}
|
||||
$dt0 = $invtables[0];
|
||||
$dt1 = $invtables[1];
|
||||
$dt2 = $invtables[2];
|
||||
$dt3 = $invtables[3];
|
||||
$isbox = $invtables[4];
|
||||
|
||||
$state = array();
|
||||
$words = unpack('N*', $in);
|
||||
|
||||
$c = $this->c;
|
||||
$dw = $this->dw;
|
||||
$Nb = $this->Nb;
|
||||
$Nr = $this->Nr;
|
||||
|
||||
// addRoundKey
|
||||
$wc = $Nb - 1;
|
||||
foreach ($words as $word) {
|
||||
$state[] = $word ^ $dw[++$wc];
|
||||
}
|
||||
|
||||
$temp = array();
|
||||
for ($round = $Nr - 1; $round > 0; --$round) {
|
||||
$i = 0; // $c[0] == 0
|
||||
$j = $Nb - $c[1];
|
||||
$k = $Nb - $c[2];
|
||||
$l = $Nb - $c[3];
|
||||
|
||||
while ($i < $Nb) {
|
||||
$temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^
|
||||
$dt1[$state[$j] >> 16 & 0x000000FF] ^
|
||||
$dt2[$state[$k] >> 8 & 0x000000FF] ^
|
||||
$dt3[$state[$l] & 0x000000FF] ^
|
||||
$dw[++$wc];
|
||||
++$i;
|
||||
$j = ($j + 1) % $Nb;
|
||||
$k = ($k + 1) % $Nb;
|
||||
$l = ($l + 1) % $Nb;
|
||||
}
|
||||
$state = $temp;
|
||||
}
|
||||
|
||||
// invShiftRows + invSubWord + addRoundKey
|
||||
$i = 0; // $c[0] == 0
|
||||
$j = $Nb - $c[1];
|
||||
$k = $Nb - $c[2];
|
||||
$l = $Nb - $c[3];
|
||||
|
||||
while ($i < $Nb) {
|
||||
$word = ($state[$i] & 0xFF000000) |
|
||||
($state[$j] & 0x00FF0000) |
|
||||
($state[$k] & 0x0000FF00) |
|
||||
($state[$l] & 0x000000FF);
|
||||
|
||||
$temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] |
|
||||
($isbox[$word >> 8 & 0x000000FF] << 8) |
|
||||
($isbox[$word >> 16 & 0x000000FF] << 16) |
|
||||
($isbox[$word >> 24 & 0x000000FF] << 24));
|
||||
++$i;
|
||||
$j = ($j + 1) % $Nb;
|
||||
$k = ($k + 1) % $Nb;
|
||||
$l = ($l + 1) % $Nb;
|
||||
}
|
||||
|
||||
switch ($Nb) {
|
||||
case 8:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
|
||||
case 7:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
|
||||
case 6:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
|
||||
case 5:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
|
||||
default:
|
||||
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
{
|
||||
// Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
|
||||
// See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
|
||||
static $rcon = array(0,
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
||||
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
|
||||
0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
|
||||
0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
|
||||
0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
|
||||
0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
|
||||
);
|
||||
|
||||
if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
|
||||
// already expanded
|
||||
return;
|
||||
}
|
||||
$this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size);
|
||||
|
||||
$this->Nk = $this->key_length >> 2;
|
||||
// see Rijndael-ammended.pdf#page=44
|
||||
$this->Nr = max($this->Nk, $this->Nb) + 6;
|
||||
|
||||
// shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
|
||||
// "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
|
||||
// shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
|
||||
// "Table 2: Shift offsets for different block lengths"
|
||||
switch ($this->Nb) {
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
$this->c = array(0, 1, 2, 3);
|
||||
break;
|
||||
case 7:
|
||||
$this->c = array(0, 1, 2, 4);
|
||||
break;
|
||||
case 8:
|
||||
$this->c = array(0, 1, 3, 4);
|
||||
}
|
||||
|
||||
$w = array_values(unpack('N*words', $this->key));
|
||||
|
||||
$length = $this->Nb * ($this->Nr + 1);
|
||||
for ($i = $this->Nk; $i < $length; $i++) {
|
||||
$temp = $w[$i - 1];
|
||||
if ($i % $this->Nk == 0) {
|
||||
// according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
|
||||
// on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
|
||||
// 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
|
||||
// with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
|
||||
$temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
|
||||
$temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
|
||||
} elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
|
||||
$temp = $this->_subWord($temp);
|
||||
}
|
||||
$w[$i] = $w[$i - $this->Nk] ^ $temp;
|
||||
}
|
||||
|
||||
// convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
|
||||
// and generate the inverse key schedule. more specifically,
|
||||
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
|
||||
// "The key expansion for the Inverse Cipher is defined as follows:
|
||||
// 1. Apply the Key Expansion.
|
||||
// 2. Apply InvMixColumn to all Round Keys except the first and the last one."
|
||||
// also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
|
||||
list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables();
|
||||
$temp = $this->w = $this->dw = array();
|
||||
for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
|
||||
if ($col == $this->Nb) {
|
||||
if ($row == 0) {
|
||||
$this->dw[0] = $this->w[0];
|
||||
} else {
|
||||
// subWord + invMixColumn + invSubWord = invMixColumn
|
||||
$j = 0;
|
||||
while ($j < $this->Nb) {
|
||||
$dw = $this->_subWord($this->w[$row][$j]);
|
||||
$temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^
|
||||
$dt1[$dw >> 16 & 0x000000FF] ^
|
||||
$dt2[$dw >> 8 & 0x000000FF] ^
|
||||
$dt3[$dw & 0x000000FF];
|
||||
$j++;
|
||||
}
|
||||
$this->dw[$row] = $temp;
|
||||
}
|
||||
|
||||
$col = 0;
|
||||
$row++;
|
||||
}
|
||||
$this->w[$row][$col] = $w[$i];
|
||||
}
|
||||
|
||||
$this->dw[$row] = $this->w[$row];
|
||||
|
||||
// Converting to 1-dim key arrays (both ascending)
|
||||
$this->dw = array_reverse($this->dw);
|
||||
$w = array_pop($this->w);
|
||||
$dw = array_pop($this->dw);
|
||||
foreach ($this->w as $r => $wr) {
|
||||
foreach ($wr as $c => $wc) {
|
||||
$w[] = $wc;
|
||||
$dw[] = $this->dw[$r][$c];
|
||||
}
|
||||
}
|
||||
$this->w = $w;
|
||||
$this->dw = $dw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs S-Box substitutions
|
||||
*
|
||||
* @access private
|
||||
* @param int $word
|
||||
*/
|
||||
function _subWord($word)
|
||||
{
|
||||
static $sbox;
|
||||
if (empty($sbox)) {
|
||||
list(, , , , $sbox) = $this->_getTables();
|
||||
}
|
||||
|
||||
return $sbox[$word & 0x000000FF] |
|
||||
($sbox[$word >> 8 & 0x000000FF] << 8) |
|
||||
($sbox[$word >> 16 & 0x000000FF] << 16) |
|
||||
($sbox[$word >> 24 & 0x000000FF] << 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the mixColumns and sboxes tables
|
||||
*
|
||||
* @see self::_encryptBlock()
|
||||
* @see self::_setupInlineCrypt()
|
||||
* @see self::_subWord()
|
||||
* @access private
|
||||
* @return array &$tables
|
||||
*/
|
||||
function &_getTables()
|
||||
{
|
||||
static $tables;
|
||||
if (empty($tables)) {
|
||||
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
|
||||
// precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
|
||||
// those are the names we'll use.
|
||||
$t3 = array_map('intval', array(
|
||||
// with array_map('intval', ...) we ensure we have only int's and not
|
||||
// some slower floats converted by php automatically on high values
|
||||
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
||||
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
||||
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
||||
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
||||
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
||||
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
||||
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
||||
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
||||
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
||||
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
||||
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
||||
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
||||
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
||||
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
||||
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
||||
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
||||
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
||||
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
||||
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
||||
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
||||
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
||||
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
||||
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
||||
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
||||
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
||||
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
||||
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
||||
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
||||
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
||||
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
||||
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
||||
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
|
||||
));
|
||||
|
||||
foreach ($t3 as $t3i) {
|
||||
$t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF);
|
||||
$t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF);
|
||||
$t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF);
|
||||
}
|
||||
|
||||
$tables = array(
|
||||
// The Precomputed mixColumns tables t0 - t3
|
||||
$t0,
|
||||
$t1,
|
||||
$t2,
|
||||
$t3,
|
||||
// The SubByte S-Box
|
||||
array(
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
||||
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
||||
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
||||
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
||||
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
||||
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
||||
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
||||
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
||||
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
||||
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
||||
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
||||
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
||||
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
||||
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
||||
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
||||
)
|
||||
);
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the inverse mixColumns and inverse sboxes tables
|
||||
*
|
||||
* @see self::_decryptBlock()
|
||||
* @see self::_setupInlineCrypt()
|
||||
* @see self::_setupKey()
|
||||
* @access private
|
||||
* @return array &$tables
|
||||
*/
|
||||
function &_getInvTables()
|
||||
{
|
||||
static $tables;
|
||||
if (empty($tables)) {
|
||||
$dt3 = array_map('intval', array(
|
||||
0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
|
||||
0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
|
||||
0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
|
||||
0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
|
||||
0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
|
||||
0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
|
||||
0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
|
||||
0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
|
||||
0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
|
||||
0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
|
||||
0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
|
||||
0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
|
||||
0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
|
||||
0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
|
||||
0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
|
||||
0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
|
||||
0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
|
||||
0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
|
||||
0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
|
||||
0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
|
||||
0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
|
||||
0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
|
||||
0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
|
||||
0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
|
||||
0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
|
||||
0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
|
||||
0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
|
||||
0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
|
||||
0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
|
||||
0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
|
||||
0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
|
||||
0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
|
||||
));
|
||||
|
||||
foreach ($dt3 as $dt3i) {
|
||||
$dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF);
|
||||
$dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
|
||||
$dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
|
||||
};
|
||||
|
||||
$tables = array(
|
||||
// The Precomputed inverse mixColumns tables dt0 - dt3
|
||||
$dt0,
|
||||
$dt1,
|
||||
$dt2,
|
||||
$dt3,
|
||||
// The inverse SubByte S-Box
|
||||
array(
|
||||
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
||||
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
|
||||
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
|
||||
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
|
||||
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
|
||||
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
|
||||
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
|
||||
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
|
||||
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
|
||||
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
|
||||
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
|
||||
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
|
||||
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
|
||||
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
|
||||
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
||||
)
|
||||
);
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the performance-optimized function for de/encrypt()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
// Note: _setupInlineCrypt() will be called only if $this->changed === true
|
||||
// So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
|
||||
// However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
|
||||
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
// The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
|
||||
$w = $this->w;
|
||||
$dw = $this->dw;
|
||||
$init_encrypt = '';
|
||||
$init_decrypt = '';
|
||||
break;
|
||||
default:
|
||||
for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
|
||||
$w[] = '$w[' . $i . ']';
|
||||
$dw[] = '$dw[' . $i . ']';
|
||||
}
|
||||
$init_encrypt = '$w = $self->w;';
|
||||
$init_decrypt = '$dw = $self->dw;';
|
||||
}
|
||||
|
||||
$Nr = $this->Nr;
|
||||
$Nb = $this->Nb;
|
||||
$c = $this->c;
|
||||
|
||||
// Generating encrypt code:
|
||||
$init_encrypt.= '
|
||||
static $tables;
|
||||
if (empty($tables)) {
|
||||
$tables = &$self->_getTables();
|
||||
}
|
||||
$t0 = $tables[0];
|
||||
$t1 = $tables[1];
|
||||
$t2 = $tables[2];
|
||||
$t3 = $tables[3];
|
||||
$sbox = $tables[4];
|
||||
';
|
||||
|
||||
$s = 'e';
|
||||
$e = 's';
|
||||
$wc = $Nb - 1;
|
||||
|
||||
// Preround: addRoundKey
|
||||
$encrypt_block = '$in = unpack("N*", $in);'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
|
||||
}
|
||||
|
||||
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
||||
for ($round = 1; $round < $Nr; ++$round) {
|
||||
list($s, $e) = array($e, $s);
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$t0[($'.$s.$i .' >> 24) & 0xff] ^
|
||||
$t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
|
||||
$t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
|
||||
$t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
|
||||
'.$w[++$wc].";\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Finalround: subWord + shiftRows + addRoundKey
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$sbox[ $'.$e.$i.' & 0xff] |
|
||||
($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
||||
($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
||||
($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
||||
}
|
||||
$encrypt_block .= '$in = pack("N*"'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$encrypt_block.= ',
|
||||
($'.$e.$i .' & '.((int)0xFF000000).') ^
|
||||
($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
||||
($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
||||
($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^
|
||||
'.$w[$i]."\n";
|
||||
}
|
||||
$encrypt_block .= ');';
|
||||
|
||||
// Generating decrypt code:
|
||||
$init_decrypt.= '
|
||||
static $invtables;
|
||||
if (empty($invtables)) {
|
||||
$invtables = &$self->_getInvTables();
|
||||
}
|
||||
$dt0 = $invtables[0];
|
||||
$dt1 = $invtables[1];
|
||||
$dt2 = $invtables[2];
|
||||
$dt3 = $invtables[3];
|
||||
$isbox = $invtables[4];
|
||||
';
|
||||
|
||||
$s = 'e';
|
||||
$e = 's';
|
||||
$wc = $Nb - 1;
|
||||
|
||||
// Preround: addRoundKey
|
||||
$decrypt_block = '$in = unpack("N*", $in);'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
|
||||
}
|
||||
|
||||
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
||||
for ($round = 1; $round < $Nr; ++$round) {
|
||||
list($s, $e) = array($e, $s);
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$dt0[($'.$s.$i .' >> 24) & 0xff] ^
|
||||
$dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
|
||||
$dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
|
||||
$dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
|
||||
'.$dw[++$wc].";\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Finalround: subWord + shiftRows + addRoundKey
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.=
|
||||
'$'.$e.$i.' =
|
||||
$isbox[ $'.$e.$i.' & 0xff] |
|
||||
($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
||||
($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
||||
($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
||||
}
|
||||
$decrypt_block .= '$in = pack("N*"'."\n";
|
||||
for ($i = 0; $i < $Nb; ++$i) {
|
||||
$decrypt_block.= ',
|
||||
($'.$e.$i. ' & '.((int)0xFF000000).') ^
|
||||
($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
||||
($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
||||
($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^
|
||||
'.$dw[$i]."\n";
|
||||
}
|
||||
$decrypt_block .= ');';
|
||||
|
||||
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
|
||||
array(
|
||||
'init_crypt' => '',
|
||||
'init_encrypt' => $init_encrypt,
|
||||
'init_decrypt' => $init_decrypt,
|
||||
'encrypt_block' => $encrypt_block,
|
||||
'decrypt_block' => $decrypt_block
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
@ -1,19 +1,18 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Triple DES.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/TripleDES.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $des = new Crypt_TripleDES();
|
||||
* $des = new \phpseclib\Crypt\TripleDES();
|
||||
*
|
||||
* $des->setKey('abcdefghijklmnopqrstuvwx');
|
||||
*
|
||||
@ -27,99 +26,64 @@
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Crypt_TripleDES
|
||||
* @package TripleDES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include Crypt_DES
|
||||
*/
|
||||
if (!class_exists('Crypt_DES')) {
|
||||
require_once('DES.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt / decrypt using inner chaining
|
||||
*
|
||||
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
|
||||
*/
|
||||
define('CRYPT_DES_MODE_3CBC', -2);
|
||||
|
||||
/**
|
||||
* Encrypt / decrypt using outer chaining
|
||||
*
|
||||
* Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
|
||||
*/
|
||||
define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Triple DES.
|
||||
*
|
||||
* @package TripleDES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.1.0
|
||||
* @access public
|
||||
* @package Crypt_TripleDES
|
||||
*/
|
||||
class Crypt_TripleDES extends Crypt_DES {
|
||||
class TripleDES extends DES
|
||||
{
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* Encrypt / decrypt using inner chaining
|
||||
*
|
||||
* @see Crypt_DES::password_key_size
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3).
|
||||
*/
|
||||
const MODE_3CBC = -2;
|
||||
|
||||
/**
|
||||
* Encrypt / decrypt using outer chaining
|
||||
*
|
||||
* Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC.
|
||||
*/
|
||||
const MODE_CBC3 = Base::MODE_CBC;
|
||||
|
||||
/**
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\TripleDES::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 24;
|
||||
var $key_length = 24;
|
||||
|
||||
/**
|
||||
* The default salt used by setPassword()
|
||||
*
|
||||
* @see Crypt_Base::password_default_salt
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::password_default_salt
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $password_default_salt = 'phpseclib';
|
||||
|
||||
/**
|
||||
* The namespace used by the cipher for its constants.
|
||||
*
|
||||
* @see Crypt_DES::const_namespace
|
||||
* @see Crypt_Base::const_namespace
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $const_namespace = 'DES';
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_DES::cipher_name_mcrypt
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\DES::cipher_name_mcrypt
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'tripledes';
|
||||
@ -127,8 +91,8 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 750;
|
||||
@ -136,27 +100,27 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* max possible size of $key
|
||||
*
|
||||
* @see Crypt_TripleDES::setKey()
|
||||
* @see Crypt_DES::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @see \phpseclib\Crypt\DES::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key_size_max = 24;
|
||||
var $key_length_max = 24;
|
||||
|
||||
/**
|
||||
* Internal flag whether using CRYPT_DES_MODE_3CBC or not
|
||||
* Internal flag whether using self::MODE_3CBC or not
|
||||
*
|
||||
* @var Boolean
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $mode_3cbc;
|
||||
|
||||
/**
|
||||
* The Crypt_DES objects
|
||||
* The \phpseclib\Crypt\DES objects
|
||||
*
|
||||
* Used only if $mode_3cbc === true
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $des;
|
||||
@ -164,65 +128,83 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
* Determines whether or not the mcrypt or OpenSSL extensions should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_DES_MODE_ECB
|
||||
* - \phpseclib\Crypt\Base::MODE_ECB
|
||||
*
|
||||
* - CRYPT_DES_MODE_CBC
|
||||
* - \phpseclib\Crypt\Base::MODE_CBC
|
||||
*
|
||||
* - CRYPT_DES_MODE_CTR
|
||||
* - \phpseclib\Crypt\Base::MODE_CTR
|
||||
*
|
||||
* - CRYPT_DES_MODE_CFB
|
||||
* - \phpseclib\Crypt\Base::MODE_CFB
|
||||
*
|
||||
* - CRYPT_DES_MODE_OFB
|
||||
* - \phpseclib\Crypt\Base::MODE_OFB
|
||||
*
|
||||
* - CRYPT_DES_MODE_3CBC
|
||||
* - \phpseclib\Crypt\TripleDES::MODE_3CB
|
||||
*
|
||||
* If not explictly set, CRYPT_DES_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_DES::Crypt_DES()
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @see \phpseclib\Crypt\DES::__construct()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $mode
|
||||
* @access public
|
||||
*/
|
||||
function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
// In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
|
||||
// In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
|
||||
// and additional flag us internally as 3CBC
|
||||
case CRYPT_DES_MODE_3CBC:
|
||||
parent::Crypt_DES(CRYPT_DES_MODE_CBC);
|
||||
case self::MODE_3CBC:
|
||||
parent::__construct(Base::MODE_CBC);
|
||||
$this->mode_3cbc = true;
|
||||
|
||||
// This three $des'es will do the 3CBC work (if $key > 64bits)
|
||||
$this->des = array(
|
||||
new Crypt_DES(CRYPT_DES_MODE_CBC),
|
||||
new Crypt_DES(CRYPT_DES_MODE_CBC),
|
||||
new Crypt_DES(CRYPT_DES_MODE_CBC),
|
||||
new DES(Base::MODE_CBC),
|
||||
new DES(Base::MODE_CBC),
|
||||
new DES(Base::MODE_CBC),
|
||||
);
|
||||
|
||||
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
|
||||
// we're going to be doing the padding, ourselves, so disable it in the \phpseclib\Crypt\DES objects
|
||||
$this->des[0]->disablePadding();
|
||||
$this->des[1]->disablePadding();
|
||||
$this->des[2]->disablePadding();
|
||||
break;
|
||||
// If not 3CBC, we init as usual
|
||||
default:
|
||||
parent::Crypt_DES($mode);
|
||||
parent::__construct($mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector. (optional)
|
||||
* Test for engine validity
|
||||
*
|
||||
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
|
||||
* to be all zero's.
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see Crypt_Base::setIV()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @param String $iv
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
$this->cipher_name_openssl_ecb = 'des-ede3';
|
||||
$mode = $this->_openssl_translate_mode();
|
||||
$this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector.
|
||||
*
|
||||
* SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setIV()
|
||||
* @access public
|
||||
* @param string $iv
|
||||
*/
|
||||
function setIV($iv)
|
||||
{
|
||||
@ -234,39 +216,66 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 128 and 192 bits.
|
||||
*
|
||||
* If you want to use a 64-bit key use DES.php
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base:setKeyLength()
|
||||
* @access public
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported');
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
|
||||
* 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
|
||||
* Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys.
|
||||
*
|
||||
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
||||
*
|
||||
* @access public
|
||||
* @see Crypt_DES::setKey()
|
||||
* @see Crypt_Base::setKey()
|
||||
* @param String $key
|
||||
* @see \phpseclib\Crypt\DES::setKey()
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
$length = strlen($key);
|
||||
if ($length > 8) {
|
||||
$key = str_pad(substr($key, 0, 24), 24, chr(0));
|
||||
// if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
|
||||
// http://php.net/function.mcrypt-encrypt#47973
|
||||
//$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
|
||||
} else {
|
||||
$key = str_pad($key, 8, chr(0));
|
||||
if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
|
||||
throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
|
||||
}
|
||||
parent::setKey($key);
|
||||
|
||||
// And in case of CRYPT_DES_MODE_3CBC:
|
||||
// if key <= 64bits we not need the 3 $des to work,
|
||||
// because we will then act as regular DES-CBC with just a <= 64bit key.
|
||||
// So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
|
||||
if ($this->mode_3cbc && $length > 8) {
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
$key.= substr($key, 0, 8);
|
||||
case 24:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported');
|
||||
}
|
||||
|
||||
// copied from Base::setKey()
|
||||
$this->key = $key;
|
||||
$this->key_length = strlen($key);
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
|
||||
if ($this->mode_3cbc) {
|
||||
$this->des[0]->setKey(substr($key, 0, 8));
|
||||
$this->des[1]->setKey(substr($key, 8, 8));
|
||||
$this->des[2]->setKey(substr($key, 16, 8));
|
||||
@ -276,21 +285,25 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* @see Crypt_Base::encrypt()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @access public
|
||||
* @param String $plaintext
|
||||
* @return String $cipertext
|
||||
* @param string $plaintext
|
||||
* @return string $cipertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
// parent::en/decrypt() is able to do all the work for all modes and keylengths,
|
||||
// except for: CRYPT_DES_MODE_3CBC (inner chaining CBC) with a key > 64bits
|
||||
// except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits
|
||||
|
||||
// if the key is smaller then 8, do what we'd normally do
|
||||
if ($this->mode_3cbc && strlen($this->key) > 8) {
|
||||
return $this->des[2]->encrypt(
|
||||
$this->des[1]->decrypt(
|
||||
$this->des[0]->encrypt($this->_pad($plaintext))));
|
||||
$this->des[0]->encrypt(
|
||||
$this->_pad($plaintext)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return parent::encrypt($plaintext);
|
||||
@ -299,17 +312,23 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Decrypts a message.
|
||||
*
|
||||
* @see Crypt_Base::decrypt()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @access public
|
||||
* @param String $ciphertext
|
||||
* @return String $plaintext
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->mode_3cbc && strlen($this->key) > 8) {
|
||||
return $this->_unpad($this->des[0]->decrypt(
|
||||
return $this->_unpad(
|
||||
$this->des[0]->decrypt(
|
||||
$this->des[1]->encrypt(
|
||||
$this->des[2]->decrypt(str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")))));
|
||||
$this->des[2]->decrypt(
|
||||
str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return parent::decrypt($ciphertext);
|
||||
@ -344,13 +363,13 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
||||
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
||||
*
|
||||
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
|
||||
* Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\DES() object changes after each
|
||||
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
||||
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
||||
* however, they are also less intuitive and more likely to cause you problems.
|
||||
*
|
||||
* @see Crypt_Base::enableContinuousBuffer()
|
||||
* @see Crypt_TripleDES::disableContinuousBuffer()
|
||||
* @see \phpseclib\Crypt\Base::enableContinuousBuffer()
|
||||
* @see self::disableContinuousBuffer()
|
||||
* @access public
|
||||
*/
|
||||
function enableContinuousBuffer()
|
||||
@ -368,8 +387,8 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
*
|
||||
* The default behavior.
|
||||
*
|
||||
* @see Crypt_Base::disableContinuousBuffer()
|
||||
* @see Crypt_TripleDES::enableContinuousBuffer()
|
||||
* @see \phpseclib\Crypt\Base::disableContinuousBuffer()
|
||||
* @see self::enableContinuousBuffer()
|
||||
* @access public
|
||||
*/
|
||||
function disableContinuousBuffer()
|
||||
@ -385,8 +404,8 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Creates the key schedule
|
||||
*
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\DES::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -416,7 +435,24 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
// setup our key
|
||||
parent::_setupKey();
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
/**
|
||||
* Sets the internal crypt engine
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @see \phpseclib\Crypt\Base::setPreferredEngine()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function setPreferredEngine($engine)
|
||||
{
|
||||
if ($this->mode_3cbc) {
|
||||
$this->des[0]->setPreferredEngine($engine);
|
||||
$this->des[1]->setPreferredEngine($engine);
|
||||
$this->des[2]->setPreferredEngine($engine);
|
||||
}
|
||||
|
||||
return parent::setPreferredEngine($engine);
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Twofish.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -15,9 +14,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/Twofish.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $twofish = new Crypt_Twofish();
|
||||
* $twofish = new \phpseclib\Crypt\Twofish();
|
||||
*
|
||||
* $twofish->setKey('12345678901234567890123456789012');
|
||||
*
|
||||
@ -27,120 +26,32 @@
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Crypt_Twofish
|
||||
* @package Twofish
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 1.0
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include Crypt_Base
|
||||
*
|
||||
* Base cipher class
|
||||
*/
|
||||
if (!class_exists('Crypt_Base')) {
|
||||
require_once('Base.php');
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see Crypt_Twofish::encrypt()
|
||||
* @see Crypt_Twofish::decrypt()
|
||||
*/
|
||||
/**
|
||||
* Encrypt / decrypt using the Counter mode.
|
||||
*
|
||||
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
|
||||
/**
|
||||
* Encrypt / decrypt using the Electronic Code Book mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Code Book Chaining mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see Crypt_Twofish::Crypt_Twofish()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Twofish.
|
||||
*
|
||||
* @package Twofish
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||
* @version 1.0
|
||||
* @access public
|
||||
* @package Crypt_Twofish
|
||||
*/
|
||||
class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The namespace used by the cipher for its constants.
|
||||
*
|
||||
* @see Crypt_Base::const_namespace
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $const_namespace = 'TWOFISH';
|
||||
|
||||
class Twofish extends Base
|
||||
{
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'twofish';
|
||||
@ -148,8 +59,8 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 800;
|
||||
@ -157,10 +68,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Q-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $q0 = array (
|
||||
var $q0 = array(
|
||||
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
|
||||
0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
|
||||
0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
|
||||
@ -198,10 +109,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Q-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $q1 = array (
|
||||
var $q1 = array(
|
||||
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
|
||||
0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
|
||||
0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
|
||||
@ -239,10 +150,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m0 = array (
|
||||
var $m0 = array(
|
||||
0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
|
||||
0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
|
||||
0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
|
||||
@ -280,10 +191,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m1 = array (
|
||||
var $m1 = array(
|
||||
0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
|
||||
0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
|
||||
0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
|
||||
@ -321,10 +232,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m2 = array (
|
||||
var $m2 = array(
|
||||
0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
|
||||
0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
|
||||
0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
|
||||
@ -362,10 +273,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m3 = array (
|
||||
var $m3 = array(
|
||||
0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
|
||||
0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
|
||||
0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
|
||||
@ -403,7 +314,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key Schedule Array
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $K = array();
|
||||
@ -411,7 +322,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 0
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S0 = array();
|
||||
@ -419,7 +330,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 1
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S1 = array();
|
||||
@ -427,7 +338,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 2
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S2 = array();
|
||||
@ -435,7 +346,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 3
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S3 = array();
|
||||
@ -443,75 +354,86 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Holds the last used key
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* @see Crypt_Twofish::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_ECB
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_CBC
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_CTR
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_CFB
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_OFB
|
||||
*
|
||||
* If not explictly set, CRYPT_TWOFISH_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_Twofish($mode = CRYPT_TWOFISH_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 128, 192 or 256 bits
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
|
||||
* If the key is less than 256-bits we round the length up to the closest valid key length,
|
||||
* padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
|
||||
* Rijndael supports five different key lengths
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @see Crypt_Base::setKey()
|
||||
* @param String $key
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
$keylength = strlen($key);
|
||||
switch (true) {
|
||||
case $keylength <= 16:
|
||||
$key = str_pad($key, 16, "\0");
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
case $keylength <= 24:
|
||||
$key = str_pad($key, 24, "\0");
|
||||
break;
|
||||
case $keylength < 32:
|
||||
$key = str_pad($key, 32, "\0");
|
||||
break;
|
||||
case $keylength > 32:
|
||||
$key = substr($key, 0, 32);
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -536,9 +458,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
|
||||
switch (strlen($this->key)) {
|
||||
case 16:
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
|
||||
$m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
|
||||
@ -559,9 +481,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
|
||||
@ -583,10 +505,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
}
|
||||
break;
|
||||
default: // 32
|
||||
list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
|
||||
list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
|
||||
@ -619,9 +541,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
* _mdsrem function using by the twofish cipher algorithm
|
||||
*
|
||||
* @access private
|
||||
* @param String $A
|
||||
* @param String $B
|
||||
* @return Array
|
||||
* @param string $A
|
||||
* @param string $B
|
||||
* @return array
|
||||
*/
|
||||
function _mdsrem($A, $B)
|
||||
{
|
||||
@ -648,7 +570,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$u^= 0x7fffffff & ($t >> 1);
|
||||
|
||||
// Add the modular polynomial on underflow.
|
||||
if ($t & 0x01) $u^= 0xa6 ;
|
||||
if ($t & 0x01) {
|
||||
$u^= 0xa6 ;
|
||||
}
|
||||
|
||||
// Remove t * (a + 1/a) * (x^3 + x).
|
||||
$B^= ($u << 24) | ($u << 8);
|
||||
@ -665,8 +589,8 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -709,18 +633,20 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
return pack("V4", $K[4] ^ $R2,
|
||||
$K[5] ^ $R3,
|
||||
$K[6] ^ $R0,
|
||||
$K[7] ^ $R1);
|
||||
// @codingStandardsIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -763,38 +689,38 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
return pack("V4", $K[0] ^ $R2,
|
||||
$K[1] ^ $R3,
|
||||
$K[2] ^ $R0,
|
||||
$K[3] ^ $R1);
|
||||
// @codingStandardsIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the performance-optimized function for de/encrypt()
|
||||
*
|
||||
* @see Crypt_Base::_setupInlineCrypt()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
// (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$code_hash = md5(str_pad("Crypt_Twofish, {$this->mode}, ", 32, "\0") . $this->key);
|
||||
break;
|
||||
default:
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_Twofish, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$K = $this->K;
|
||||
|
||||
$init_crypt = '
|
||||
static $S0, $S1, $S2, $S3;
|
||||
if (!$S0) {
|
||||
@ -812,7 +738,6 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
for ($i = 0; $i < 40; ++$i) {
|
||||
$K[] = '$K_' . $i;
|
||||
}
|
||||
|
||||
$init_crypt = '
|
||||
$S0 = $self->S0;
|
||||
$S1 = $self->S1;
|
||||
@ -919,6 +844,3 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
26
extlib/phpseclib/Exception/BadConfigurationException.php
Normal file
26
extlib/phpseclib/Exception/BadConfigurationException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BadConfigurationException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package BadConfigurationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* BadConfigurationException
|
||||
*
|
||||
* @package BadConfigurationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class BadConfigurationException extends \RuntimeException
|
||||
{
|
||||
}
|
26
extlib/phpseclib/Exception/FileNotFoundException.php
Normal file
26
extlib/phpseclib/Exception/FileNotFoundException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FileNotFoundException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package FileNotFoundException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* FileNotFoundException
|
||||
*
|
||||
* @package FileNotFoundException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class FileNotFoundException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NoSupportedAlgorithmsException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package NoSupportedAlgorithmsException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* NoSupportedAlgorithmsException
|
||||
*
|
||||
* @package NoSupportedAlgorithmsException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class NoSupportedAlgorithmsException extends \RuntimeException
|
||||
{
|
||||
}
|
26
extlib/phpseclib/Exception/UnsupportedAlgorithmException.php
Normal file
26
extlib/phpseclib/Exception/UnsupportedAlgorithmException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UnsupportedAlgorithmException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package UnsupportedAlgorithmException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* UnsupportedAlgorithmException
|
||||
*
|
||||
* @package UnsupportedAlgorithmException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class UnsupportedAlgorithmException extends \RuntimeException
|
||||
{
|
||||
}
|
574
extlib/phpseclib/File/ANSI.php
Normal file
574
extlib/phpseclib/File/ANSI.php
Normal file
@ -0,0 +1,574 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP ANSI Decoder
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* If you call read() in \phpseclib\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
|
||||
* They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a
|
||||
* {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what
|
||||
* color to display them in, etc. \phpseclib\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
|
||||
*
|
||||
* @category File
|
||||
* @package ANSI
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2012 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\File;
|
||||
|
||||
/**
|
||||
* Pure-PHP ANSI Decoder
|
||||
*
|
||||
* @package ANSI
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class ANSI
|
||||
{
|
||||
/**
|
||||
* Max Width
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_x;
|
||||
|
||||
/**
|
||||
* Max Height
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_y;
|
||||
|
||||
/**
|
||||
* Max History
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_history;
|
||||
|
||||
/**
|
||||
* History
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $history;
|
||||
|
||||
/**
|
||||
* History Attributes
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $history_attrs;
|
||||
|
||||
/**
|
||||
* Current Column
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $x;
|
||||
|
||||
/**
|
||||
* Current Row
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $y;
|
||||
|
||||
/**
|
||||
* Old Column
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $old_x;
|
||||
|
||||
/**
|
||||
* Old Row
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $old_y;
|
||||
|
||||
/**
|
||||
* An empty attribute cell
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $base_attr_cell;
|
||||
|
||||
/**
|
||||
* The current attribute cell
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $attr_cell;
|
||||
|
||||
/**
|
||||
* An empty attribute row
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $attr_row;
|
||||
|
||||
/**
|
||||
* The current screen text
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $screen;
|
||||
|
||||
/**
|
||||
* The current screen attributes
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $attrs;
|
||||
|
||||
/**
|
||||
* Current ANSI code
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $ansi;
|
||||
|
||||
/**
|
||||
* Tokenization
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $tokenization;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @return \phpseclib\File\ANSI
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$attr_cell = new \stdClass();
|
||||
$attr_cell->bold = false;
|
||||
$attr_cell->underline = false;
|
||||
$attr_cell->blink = false;
|
||||
$attr_cell->background = 'black';
|
||||
$attr_cell->foreground = 'white';
|
||||
$attr_cell->reverse = false;
|
||||
$this->base_attr_cell = clone $attr_cell;
|
||||
$this->attr_cell = clone $attr_cell;
|
||||
|
||||
$this->setHistory(200);
|
||||
$this->setDimensions(80, 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set terminal width and height
|
||||
*
|
||||
* Resets the screen as well
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @access public
|
||||
*/
|
||||
function setDimensions($x, $y)
|
||||
{
|
||||
$this->max_x = $x - 1;
|
||||
$this->max_y = $y - 1;
|
||||
$this->x = $this->y = 0;
|
||||
$this->history = $this->history_attrs = array();
|
||||
$this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell);
|
||||
$this->screen = array_fill(0, $this->max_y + 1, '');
|
||||
$this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
|
||||
$this->ansi = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of lines that should be logged past the terminal height
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @access public
|
||||
*/
|
||||
function setHistory($history)
|
||||
{
|
||||
$this->max_history = $history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a string
|
||||
*
|
||||
* @param string $source
|
||||
* @access public
|
||||
*/
|
||||
function loadString($source)
|
||||
{
|
||||
$this->setDimensions($this->max_x + 1, $this->max_y + 1);
|
||||
$this->appendString($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appdend a string
|
||||
*
|
||||
* @param string $source
|
||||
* @access public
|
||||
*/
|
||||
function appendString($source)
|
||||
{
|
||||
$this->tokenization = array('');
|
||||
for ($i = 0; $i < strlen($source); $i++) {
|
||||
if (strlen($this->ansi)) {
|
||||
$this->ansi.= $source[$i];
|
||||
$chr = ord($source[$i]);
|
||||
// http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
|
||||
// single character CSI's not currently supported
|
||||
switch (true) {
|
||||
case $this->ansi == "\x1B=":
|
||||
$this->ansi = '';
|
||||
continue 2;
|
||||
case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['):
|
||||
case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126:
|
||||
break;
|
||||
default:
|
||||
continue 2;
|
||||
}
|
||||
$this->tokenization[] = $this->ansi;
|
||||
$this->tokenization[] = '';
|
||||
// http://ascii-table.com/ansi-escape-sequences-vt-100.php
|
||||
switch ($this->ansi) {
|
||||
case "\x1B[H": // Move cursor to upper left corner
|
||||
$this->old_x = $this->x;
|
||||
$this->old_y = $this->y;
|
||||
$this->x = $this->y = 0;
|
||||
break;
|
||||
case "\x1B[J": // Clear screen from cursor down
|
||||
$this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
|
||||
$this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
|
||||
|
||||
$this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y));
|
||||
$this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row));
|
||||
|
||||
if (count($this->history) == $this->max_history) {
|
||||
array_shift($this->history);
|
||||
array_shift($this->history_attrs);
|
||||
}
|
||||
case "\x1B[K": // Clear screen from cursor right
|
||||
$this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
|
||||
|
||||
array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell));
|
||||
break;
|
||||
case "\x1B[2K": // Clear entire line
|
||||
$this->screen[$this->y] = str_repeat(' ', $this->x);
|
||||
$this->attrs[$this->y] = $this->attr_row;
|
||||
break;
|
||||
case "\x1B[?1h": // set cursor key to application
|
||||
case "\x1B[?25h": // show the cursor
|
||||
case "\x1B(B": // set united states g0 character set
|
||||
break;
|
||||
case "\x1BE": // Move to next line
|
||||
$this->_newLine();
|
||||
$this->x = 0;
|
||||
break;
|
||||
default:
|
||||
switch (true) {
|
||||
case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines
|
||||
$this->old_y = $this->y;
|
||||
$this->y+= $match[1];
|
||||
break;
|
||||
case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
|
||||
$this->old_x = $this->x;
|
||||
$this->old_y = $this->y;
|
||||
$this->x = $match[2] - 1;
|
||||
$this->y = $match[1] - 1;
|
||||
break;
|
||||
case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
|
||||
$this->old_x = $this->x;
|
||||
$this->x+= $match[1];
|
||||
break;
|
||||
case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
|
||||
$this->old_x = $this->x;
|
||||
$this->x-= $match[1];
|
||||
break;
|
||||
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
|
||||
break;
|
||||
case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
|
||||
$attr_cell = &$this->attr_cell;
|
||||
$mods = explode(';', $match[1]);
|
||||
foreach ($mods as $mod) {
|
||||
switch ($mod) {
|
||||
case 0: // Turn off character attributes
|
||||
$attr_cell = clone $this->base_attr_cell;
|
||||
break;
|
||||
case 1: // Turn bold mode on
|
||||
$attr_cell->bold = true;
|
||||
break;
|
||||
case 4: // Turn underline mode on
|
||||
$attr_cell->underline = true;
|
||||
break;
|
||||
case 5: // Turn blinking mode on
|
||||
$attr_cell->blink = true;
|
||||
break;
|
||||
case 7: // Turn reverse video on
|
||||
$attr_cell->reverse = !$attr_cell->reverse;
|
||||
$temp = $attr_cell->background;
|
||||
$attr_cell->background = $attr_cell->foreground;
|
||||
$attr_cell->foreground = $temp;
|
||||
break;
|
||||
default: // set colors
|
||||
//$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground;
|
||||
$front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' };
|
||||
//$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
|
||||
$back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
|
||||
switch ($mod) {
|
||||
// @codingStandardsIgnoreStart
|
||||
case 30: $front = 'black'; break;
|
||||
case 31: $front = 'red'; break;
|
||||
case 32: $front = 'green'; break;
|
||||
case 33: $front = 'yellow'; break;
|
||||
case 34: $front = 'blue'; break;
|
||||
case 35: $front = 'magenta'; break;
|
||||
case 36: $front = 'cyan'; break;
|
||||
case 37: $front = 'white'; break;
|
||||
|
||||
case 40: $back = 'black'; break;
|
||||
case 41: $back = 'red'; break;
|
||||
case 42: $back = 'green'; break;
|
||||
case 43: $back = 'yellow'; break;
|
||||
case 44: $back = 'blue'; break;
|
||||
case 45: $back = 'magenta'; break;
|
||||
case 46: $back = 'cyan'; break;
|
||||
case 47: $back = 'white'; break;
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
default:
|
||||
//user_error('Unsupported attribute: ' . $mod);
|
||||
$this->ansi = '';
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//user_error("{$this->ansi} is unsupported\r\n");
|
||||
}
|
||||
}
|
||||
$this->ansi = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->tokenization[count($this->tokenization) - 1].= $source[$i];
|
||||
switch ($source[$i]) {
|
||||
case "\r":
|
||||
$this->x = 0;
|
||||
break;
|
||||
case "\n":
|
||||
$this->_newLine();
|
||||
break;
|
||||
case "\x08": // backspace
|
||||
if ($this->x) {
|
||||
$this->x--;
|
||||
$this->attrs[$this->y][$this->x] = clone $this->base_attr_cell;
|
||||
$this->screen[$this->y] = substr_replace(
|
||||
$this->screen[$this->y],
|
||||
$source[$i],
|
||||
$this->x,
|
||||
1
|
||||
);
|
||||
}
|
||||
break;
|
||||
case "\x0F": // shift
|
||||
break;
|
||||
case "\x1B": // start ANSI escape code
|
||||
$this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1);
|
||||
//if (!strlen($this->tokenization[count($this->tokenization) - 1])) {
|
||||
// array_pop($this->tokenization);
|
||||
//}
|
||||
$this->ansi.= "\x1B";
|
||||
break;
|
||||
default:
|
||||
$this->attrs[$this->y][$this->x] = clone $this->attr_cell;
|
||||
if ($this->x > strlen($this->screen[$this->y])) {
|
||||
$this->screen[$this->y] = str_repeat(' ', $this->x);
|
||||
}
|
||||
$this->screen[$this->y] = substr_replace(
|
||||
$this->screen[$this->y],
|
||||
$source[$i],
|
||||
$this->x,
|
||||
1
|
||||
);
|
||||
|
||||
if ($this->x > $this->max_x) {
|
||||
$this->x = 0;
|
||||
$this->y++;
|
||||
} else {
|
||||
$this->x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new line
|
||||
*
|
||||
* Also update the $this->screen and $this->history buffers
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _newLine()
|
||||
{
|
||||
//if ($this->y < $this->max_y) {
|
||||
// $this->y++;
|
||||
//}
|
||||
|
||||
while ($this->y >= $this->max_y) {
|
||||
$this->history = array_merge($this->history, array(array_shift($this->screen)));
|
||||
$this->screen[] = '';
|
||||
|
||||
$this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
|
||||
$this->attrs[] = $this->attr_row;
|
||||
|
||||
if (count($this->history) >= $this->max_history) {
|
||||
array_shift($this->history);
|
||||
array_shift($this->history_attrs);
|
||||
}
|
||||
|
||||
$this->y--;
|
||||
}
|
||||
$this->y++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current coordinate without preformating
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _processCoordinate($last_attr, $cur_attr, $char)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
if ($last_attr != $cur_attr) {
|
||||
$close = $open = '';
|
||||
if ($last_attr->foreground != $cur_attr->foreground) {
|
||||
if ($cur_attr->foreground != 'white') {
|
||||
$open.= '<span style="color: ' . $cur_attr->foreground . '">';
|
||||
}
|
||||
if ($last_attr->foreground != 'white') {
|
||||
$close = '</span>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->background != $cur_attr->background) {
|
||||
if ($cur_attr->background != 'black') {
|
||||
$open.= '<span style="background: ' . $cur_attr->background . '">';
|
||||
}
|
||||
if ($last_attr->background != 'black') {
|
||||
$close = '</span>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->bold != $cur_attr->bold) {
|
||||
if ($cur_attr->bold) {
|
||||
$open.= '<b>';
|
||||
} else {
|
||||
$close = '</b>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->underline != $cur_attr->underline) {
|
||||
if ($cur_attr->underline) {
|
||||
$open.= '<u>';
|
||||
} else {
|
||||
$close = '</u>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->blink != $cur_attr->blink) {
|
||||
if ($cur_attr->blink) {
|
||||
$open.= '<blink>';
|
||||
} else {
|
||||
$close = '</blink>' . $close;
|
||||
}
|
||||
}
|
||||
$output.= $close . $open;
|
||||
}
|
||||
|
||||
$output.= htmlspecialchars($char);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current screen without preformating
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _getScreen()
|
||||
{
|
||||
$output = '';
|
||||
$last_attr = $this->base_attr_cell;
|
||||
for ($i = 0; $i <= $this->max_y; $i++) {
|
||||
for ($j = 0; $j <= $this->max_x; $j++) {
|
||||
$cur_attr = $this->attrs[$i][$j];
|
||||
$output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : '');
|
||||
$last_attr = $this->attrs[$i][$j];
|
||||
}
|
||||
$output.= "\r\n";
|
||||
}
|
||||
$output = substr($output, 0, -2);
|
||||
// close any remaining open tags
|
||||
$output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, '');
|
||||
return rtrim($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current screen
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getScreen()
|
||||
{
|
||||
return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $this->_getScreen() . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current screen and the x previous lines
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getHistory()
|
||||
{
|
||||
$scrollback = '';
|
||||
$last_attr = $this->base_attr_cell;
|
||||
for ($i = 0; $i < count($this->history); $i++) {
|
||||
for ($j = 0; $j <= $this->max_x + 1; $j++) {
|
||||
$cur_attr = $this->history_attrs[$i][$j];
|
||||
$scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : '');
|
||||
$last_attr = $this->history_attrs[$i][$j];
|
||||
}
|
||||
$scrollback.= "\r\n";
|
||||
}
|
||||
$base_attr_cell = $this->base_attr_cell;
|
||||
$this->base_attr_cell = $last_attr;
|
||||
$scrollback.= $this->_getScreen();
|
||||
$this->base_attr_cell = $base_attr_cell;
|
||||
|
||||
return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $scrollback . '</span></pre>';
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user