Back to index

lightning-sunbird  0.9+nobinonly
mac_rand.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifdef notdef
00038 #include "xp_core.h"
00039 #include "xp_file.h"
00040 #endif
00041 #include "secrng.h"
00042 #include "mcom_db.h"
00043 #ifdef XP_MAC
00044 #include <Events.h>
00045 #include <OSUtils.h>
00046 #include <QDOffscreen.h>
00047 #include <PPCToolbox.h>
00048 #include <Processes.h>
00049 #include <LowMem.h>
00050 #include <Scrap.h>
00051 
00052 /* Static prototypes */
00053 static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen);
00054 void FE_ReadScreen();
00055 
00056 static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen)
00057 {
00058     union endianness {
00059         int32 i;
00060         char c[4];
00061     } u;
00062 
00063     if (srclen <= dstlen) {
00064         memcpy(dst, src, srclen);
00065         return srclen;
00066     }
00067     u.i = 0x01020304;
00068     if (u.c[0] == 0x01) {
00069         /* big-endian case */
00070         memcpy(dst, (char*)src + (srclen - dstlen), dstlen);
00071     } else {
00072         /* little-endian case */
00073         memcpy(dst, src, dstlen);
00074     }
00075     return dstlen;
00076 }
00077 
00078 size_t RNG_GetNoise(void *buf, size_t maxbytes)
00079 {
00080     UnsignedWide microTickCount;
00081     Microseconds(&microTickCount);
00082     return CopyLowBits(buf, maxbytes,  &microTickCount, sizeof(microTickCount));
00083 }
00084 
00085 void RNG_FileForRNG(const char *filename)
00086 {   
00087     unsigned char buffer[BUFSIZ];
00088     size_t bytes;
00089 #ifdef notdef /*sigh*/
00090     XP_File file;
00091        unsigned long totalFileBytes = 0;
00092 
00093        if (filename == NULL)       /* For now, read in global history if filename is null */
00094               file = XP_FileOpen(NULL, xpGlobalHistory,XP_FILE_READ_BIN);
00095        else
00096               file = XP_FileOpen(NULL, xpURL,XP_FILE_READ_BIN);
00097     if (file != NULL) {
00098         for (;;) {
00099             bytes = XP_FileRead(buffer, sizeof(buffer), file);
00100             if (bytes == 0) break;
00101             RNG_RandomUpdate( buffer, bytes);
00102             totalFileBytes += bytes;
00103             if (totalFileBytes > 100*1024) break;       /* No more than 100 K */
00104         }
00105               XP_FileClose(file);
00106     }
00107 #endif
00108     /*
00109      * Pass yet another snapshot of our highest resolution clock into
00110      * the hash function.
00111      */
00112     bytes = RNG_GetNoise(buffer, sizeof(buffer));
00113     RNG_RandomUpdate(buffer, sizeof(buffer));
00114 }
00115 
00116 void RNG_SystemInfoForRNG()
00117 {
00118 /* Time */
00119        {
00120               unsigned long sec;
00121               size_t bytes;
00122               GetDateTime(&sec);   /* Current time since 1970 */
00123               RNG_RandomUpdate( &sec, sizeof(sec));
00124            bytes = RNG_GetNoise(&sec, sizeof(sec));
00125            RNG_RandomUpdate(&sec, bytes);
00126     }
00127 /* User specific variables */
00128        {
00129               MachineLocation loc;
00130               ReadLocation(&loc);
00131               RNG_RandomUpdate( &loc, sizeof(loc));
00132        }
00133 #if !TARGET_CARBON
00134 /* User name */
00135        {
00136               unsigned long userRef;
00137               Str32 userName;
00138               GetDefaultUser(&userRef, userName);
00139               RNG_RandomUpdate( &userRef, sizeof(userRef));
00140               RNG_RandomUpdate( userName, sizeof(userName));
00141        }
00142 #endif
00143 /* Mouse location */
00144        {
00145               Point mouseLoc;
00146               GetMouse(&mouseLoc);
00147               RNG_RandomUpdate( &mouseLoc, sizeof(mouseLoc));
00148        }
00149 /* Keyboard time threshold */
00150        {
00151               SInt16 keyTresh = LMGetKeyThresh();
00152               RNG_RandomUpdate( &keyTresh, sizeof(keyTresh));
00153        }
00154 /* Last key pressed */
00155        {
00156               SInt8 keyLast;
00157               keyLast = LMGetKbdLast();
00158               RNG_RandomUpdate( &keyLast, sizeof(keyLast));
00159        }
00160 /* Volume */
00161        {
00162               UInt8 volume = LMGetSdVolume();
00163               RNG_RandomUpdate( &volume, sizeof(volume));
00164        }
00165 #if !TARGET_CARBON
00166 /* Current directory */
00167        {
00168               SInt32 dir = LMGetCurDirStore();
00169               RNG_RandomUpdate( &dir, sizeof(dir));
00170        }
00171 #endif
00172 /* Process information about all the processes in the machine */
00173        {
00174               ProcessSerialNumber  process;
00175               ProcessInfoRec pi;
00176        
00177               process.highLongOfPSN = process.lowLongOfPSN  = kNoProcess;
00178               
00179               while (GetNextProcess(&process) == noErr)
00180               {
00181                      FSSpec fileSpec;
00182                      pi.processInfoLength = sizeof(ProcessInfoRec);
00183                      pi.processName = NULL;
00184                      pi.processAppSpec = &fileSpec;
00185                      GetProcessInformation(&process, &pi);
00186                      RNG_RandomUpdate( &pi, sizeof(pi));
00187                      RNG_RandomUpdate( &fileSpec, sizeof(fileSpec));
00188               }
00189        }
00190        
00191 #if !TARGET_CARBON
00192 /* Heap */
00193        {
00194               THz zone = LMGetTheZone();
00195               RNG_RandomUpdate( &zone, sizeof(zone));
00196        }
00197 #endif
00198        
00199 /* Screen */
00200        {
00201               GDHandle h = GetMainDevice();             /* GDHandle is **GDevice */
00202               RNG_RandomUpdate( *h, sizeof(GDevice));
00203        }
00204 
00205 #if !TARGET_CARBON
00206 /* Scrap size */
00207        {
00208               SInt32 scrapSize = LMGetScrapSize();
00209               RNG_RandomUpdate( &scrapSize, sizeof(scrapSize));
00210        }
00211 /* Scrap count */
00212        {
00213               SInt16 scrapCount = LMGetScrapCount();
00214               RNG_RandomUpdate( &scrapCount, sizeof(scrapCount));
00215        }
00216 #else
00217        {
00218            ScrapRef scrap;
00219         if (GetCurrentScrap(&scrap) == noErr) {
00220             UInt32 flavorCount;
00221             if (GetScrapFlavorCount(scrap, &flavorCount) == noErr) {
00222                 ScrapFlavorInfo* flavorInfo = (ScrapFlavorInfo*) malloc(flavorCount * sizeof(ScrapFlavorInfo));
00223                 if (flavorInfo != NULL) {
00224                     if (GetScrapFlavorInfoList(scrap, &flavorCount, flavorInfo) == noErr) {
00225                         UInt32 i;
00226                         RNG_RandomUpdate(&flavorCount, sizeof(flavorCount));
00227                         for (i = 0; i < flavorCount; ++i) {
00228                             Size flavorSize;
00229                             if (GetScrapFlavorSize(scrap, flavorInfo[i].flavorType, &flavorSize) == noErr)
00230                                 RNG_RandomUpdate(&flavorSize, sizeof(flavorSize));
00231                         }
00232                     }
00233                     free(flavorInfo);
00234                 }
00235             }
00236         }
00237     }
00238 #endif
00239 /*  File stuff, last modified, etc. */
00240        {
00241               HParamBlockRec                     pb;
00242               GetVolParmsInfoBuffer       volInfo;
00243               pb.ioParam.ioVRefNum = 0;
00244               pb.ioParam.ioNamePtr = nil;
00245               pb.ioParam.ioBuffer = (Ptr) &volInfo;
00246               pb.ioParam.ioReqCount = sizeof(volInfo);
00247               PBHGetVolParmsSync(&pb);
00248               RNG_RandomUpdate( &volInfo, sizeof(volInfo));
00249        }
00250 #if !TARGET_CARBON
00251 /* Event queue */
00252        {
00253               EvQElPtr             eventQ;
00254               for (eventQ = (EvQElPtr) LMGetEventQueue()->qHead; 
00255                             eventQ; 
00256                             eventQ = (EvQElPtr)eventQ->qLink)
00257                      RNG_RandomUpdate( &eventQ->evtQWhat, sizeof(EventRecord));
00258        }
00259 #endif
00260        FE_ReadScreen();
00261        RNG_FileForRNG(NULL);
00262 }
00263 
00264 void FE_ReadScreen()
00265 {
00266        UInt16                      coords[4];
00267        PixMapHandle         pmap;
00268        GDHandle                    gh;    
00269        UInt16                      screenHeight;
00270        UInt16                      screenWidth;                /* just what they say */
00271        UInt32                      bytesToRead;                /* number of bytes we're giving */
00272        UInt32                      offset;                                   /* offset into the graphics buffer */
00273        UInt16                      rowBytes;
00274        UInt32                      rowsToRead;
00275        float                       bytesPerPixel;                     /* dependent on buffer depth */
00276        Ptr                                p;                                        /* temporary */
00277        UInt16                      x, y, w, h;
00278 
00279        gh = LMGetMainDevice();
00280        if ( !gh )
00281               return;
00282        pmap = (**gh).gdPMap;
00283        if ( !pmap )
00284               return;
00285               
00286        RNG_GenerateGlobalRandomBytes( coords, sizeof( coords ) );
00287        
00288        /* make x and y inside the screen rect */ 
00289        screenHeight = (**pmap).bounds.bottom - (**pmap).bounds.top;
00290        screenWidth = (**pmap).bounds.right - (**pmap).bounds.left;
00291        x = coords[0] % screenWidth;
00292        y = coords[1] % screenHeight;
00293        w = ( coords[2] & 0x7F ) | 0x40;          /* Make sure that w is in the range 64..128 */
00294        h = ( coords[3] & 0x7F ) | 0x40;          /* same for h */
00295 
00296        bytesPerPixel = (**pmap).pixelSize / 8;
00297        rowBytes = (**pmap).rowBytes & 0x7FFF;
00298 
00299        /* starting address */
00300        offset = ( rowBytes * y ) + (UInt32)( (float)x * bytesPerPixel );
00301        
00302        /* don't read past the end of the pixmap's rowbytes */
00303        bytesToRead = PR_MIN(       (UInt32)( w * bytesPerPixel ),
00304                                           (UInt32)( rowBytes - ( x * bytesPerPixel ) ) );
00305 
00306        /* don't read past the end of the graphics device pixmap */
00307        rowsToRead = PR_MIN( h, 
00308                                           ( screenHeight - y ) );
00309        
00310        p = GetPixBaseAddr( pmap ) + offset;
00311        
00312        while ( rowsToRead-- )
00313        {
00314               RNG_RandomUpdate( p, bytesToRead );
00315               p += rowBytes;
00316        }
00317 }
00318 #endif