+ OSData * data;
+ IORegistryEntry * entry;
+ OSString * string = 0;
+ uuid_string_t uuid;
+
+#if CONFIG_EMBEDDED
+ entry = IORegistryEntry::fromPath( "/chosen", gIODTPlane );
+ if ( entry )
+ {
+ OSData * data1;
+
+ data1 = OSDynamicCast( OSData, entry->getProperty( "unique-chip-id" ) );
+ if ( data1 && data1->getLength( ) == 8 )
+ {
+ OSData * data2;
+
+ data2 = OSDynamicCast( OSData, entry->getProperty( "chip-id" ) );
+ if ( data2 && data2->getLength( ) == 4 )
+ {
+ SHA1_CTX context;
+ uint8_t digest[ SHA_DIGEST_LENGTH ];
+ const uuid_t space = { 0xA6, 0xDD, 0x4C, 0xCB, 0xB5, 0xE8, 0x4A, 0xF5, 0xAC, 0xDD, 0xB6, 0xDC, 0x6A, 0x05, 0x42, 0xB8 };
+
+ SHA1Init( &context );
+ SHA1Update( &context, space, sizeof( space ) );
+ SHA1Update( &context, data1->getBytesNoCopy( ), data1->getLength( ) );
+ SHA1Update( &context, data2->getBytesNoCopy( ), data2->getLength( ) );
+ SHA1Final( digest, &context );
+
+ digest[ 6 ] = ( digest[ 6 ] & 0x0F ) | 0x50;
+ digest[ 8 ] = ( digest[ 8 ] & 0x3F ) | 0x80;
+
+ uuid_unparse( digest, uuid );
+ string = OSString::withCString( uuid );
+ }
+ }
+
+ entry->release( );
+ }
+#else /* !CONFIG_EMBEDDED */
+ entry = IORegistryEntry::fromPath( "/efi/platform", gIODTPlane );
+ if ( entry )
+ {
+ data = OSDynamicCast( OSData, entry->getProperty( "system-id" ) );
+ if ( data && data->getLength( ) == 16 )
+ {
+ SHA1_CTX context;
+ uint8_t digest[ SHA_DIGEST_LENGTH ];
+ const uuid_t space = { 0x2A, 0x06, 0x19, 0x90, 0xD3, 0x8D, 0x44, 0x40, 0xA1, 0x39, 0xC4, 0x97, 0x70, 0x37, 0x65, 0xAC };
+
+ SHA1Init( &context );
+ SHA1Update( &context, space, sizeof( space ) );
+ SHA1Update( &context, data->getBytesNoCopy( ), data->getLength( ) );
+ SHA1Final( digest, &context );
+
+ digest[ 6 ] = ( digest[ 6 ] & 0x0F ) | 0x50;
+ digest[ 8 ] = ( digest[ 8 ] & 0x3F ) | 0x80;
+
+ uuid_unparse( digest, uuid );
+ string = OSString::withCString( uuid );
+ }
+
+ entry->release( );
+ }
+#endif /* !CONFIG_EMBEDDED */
+
+ if ( string == 0 )
+ {
+ entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
+ if ( entry )
+ {
+ data = OSDynamicCast( OSData, entry->getProperty( "platform-uuid" ) );
+ if ( data && data->getLength( ) == sizeof( uuid_t ) )
+ {
+ uuid_unparse( ( uint8_t * ) data->getBytesNoCopy( ), uuid );
+ string = OSString::withCString( uuid );
+ }
+
+ entry->release( );
+ }
+ }
+
+ if ( string )
+ {
+ getProvider( )->setProperty( kIOPlatformUUIDKey, string );
+ publishResource( kIOPlatformUUIDKey, string );
+
+ string->release( );
+ }
+